[Orxonox-commit 6313] r10970 - in code/branches/presentationHS15: . data/defaultConfig data/gui/layouts data/gui/scripts data/levels data/levels/templates src/libraries/util src/modules/docking src/modules/overlays/hud src/modules/weapons/weaponmodes src/orxonox/controllers src/orxonox/worldentities src/orxonox/worldentities/pawns test/util
maxima at orxonox.net
maxima at orxonox.net
Fri Dec 11 15:26:20 CET 2015
Author: maxima
Date: 2015-12-11 15:26:20 +0100 (Fri, 11 Dec 2015)
New Revision: 10970
Added:
code/branches/presentationHS15/data/levels/AITest.oxw
code/branches/presentationHS15/data/levels/expeditionSector.oxw
code/branches/presentationHS15/data/levels/shuttleAttack.oxw
code/branches/presentationHS15/data/levels/shuttleRetaliation.oxw
code/branches/presentationHS15/data/levels/templates/spaceshipShuttle.oxt
code/branches/presentationHS15/src/orxonox/controllers/ActionpointController.cc
code/branches/presentationHS15/src/orxonox/controllers/ActionpointController.h
code/branches/presentationHS15/src/orxonox/controllers/CommonController.cc
code/branches/presentationHS15/src/orxonox/controllers/CommonController.h
code/branches/presentationHS15/src/orxonox/controllers/DivisionController.cc
code/branches/presentationHS15/src/orxonox/controllers/DivisionController.h
code/branches/presentationHS15/src/orxonox/controllers/FightingController.cc
code/branches/presentationHS15/src/orxonox/controllers/FightingController.h
code/branches/presentationHS15/src/orxonox/controllers/FlyingController.cc
code/branches/presentationHS15/src/orxonox/controllers/FlyingController.h
code/branches/presentationHS15/src/orxonox/controllers/MasterController.cc
code/branches/presentationHS15/src/orxonox/controllers/MasterController.h
code/branches/presentationHS15/src/orxonox/controllers/SectionController.cc
code/branches/presentationHS15/src/orxonox/controllers/SectionController.h
code/branches/presentationHS15/src/orxonox/controllers/WingmanController.cc
code/branches/presentationHS15/src/orxonox/controllers/WingmanController.h
code/branches/presentationHS15/src/orxonox/worldentities/Actionpoint.cc
code/branches/presentationHS15/src/orxonox/worldentities/Actionpoint.h
Modified:
code/branches/presentationHS15/
code/branches/presentationHS15/data/defaultConfig/orxonox.ini
code/branches/presentationHS15/data/gui/layouts/CampaignMenu.layout
code/branches/presentationHS15/data/gui/scripts/CampaignMenu.lua
code/branches/presentationHS15/data/levels/missionOne.oxw
code/branches/presentationHS15/src/libraries/util/Math.cc
code/branches/presentationHS15/src/libraries/util/Math.h
code/branches/presentationHS15/src/modules/docking/DockingController.cc
code/branches/presentationHS15/src/modules/overlays/hud/HUDRadar.cc
code/branches/presentationHS15/src/modules/weapons/weaponmodes/MineGun.cc
code/branches/presentationHS15/src/orxonox/controllers/CMakeLists.txt
code/branches/presentationHS15/src/orxonox/controllers/FormationController.cc
code/branches/presentationHS15/src/orxonox/worldentities/CMakeLists.txt
code/branches/presentationHS15/src/orxonox/worldentities/SpawnPoint.h
code/branches/presentationHS15/src/orxonox/worldentities/TeamSpawnPoint.cc
code/branches/presentationHS15/src/orxonox/worldentities/TeamSpawnPoint.h
code/branches/presentationHS15/src/orxonox/worldentities/pawns/Pawn.h
code/branches/presentationHS15/test/util/MathTest.cc
Log:
Merged campaign and presentation. Everything seems to work fine.
Property changes on: code/branches/presentationHS15
___________________________________________________________________
Modified: svn:mergeinfo
- /code/branches/ParticleEffectsFS15:10309-10612
/code/branches/Racingbot:9388-9513
/code/branches/SciptableControllerFS15:10308-10613
/code/branches/ScriptableController:9999-10075
/code/branches/ai:6592-7033
/code/branches/ai2:8721-8880
/code/branches/bigships:8137-8588
/code/branches/buildsystem:1874-2276,2278-2400
/code/branches/buildsystem2:2506-2658
/code/branches/buildsystem3:2662-2708
/code/branches/ceguilua:1802-1808
/code/branches/chat:6527-6797
/code/branches/chat2:6836-6910
/code/branches/clangenb:10385-10609
/code/branches/console:5941-6104
/code/branches/consolecommands2:6451-7178
/code/branches/consolecommands3:7178-7283
/code/branches/core3:1572-1739
/code/branches/core4:3221-3224,3227,3234-3238,3242,3244-3250,3252-3254,3256,3259-3261,3264-3265,3268-3275,3277-3278,3280,3284-3285,3287,3289-3294,3305,3309-3310
/code/branches/core5:5768-5928,6009
/code/branches/core6:9552-9666
/code/branches/core7:10328-10623
/code/branches/data_cleanup:7537-7686
/code/branches/doc:7290-7400
/code/branches/dockingsystem:8101-8192
/code/branches/dockingsystem2:8196-8560
/code/branches/dynamicmatch:6584-7030
/code/branches/environment3:8887-8975
/code/branches/explosionChunksHS15:10641-10961
/code/branches/fabienHS15:10685-10960
/code/branches/formation:8885-8991
/code/branches/formationFS15:10320-10610
/code/branches/formationupdate:9580-9624
/code/branches/fps:6591-7072
/code/branches/gamecontent:8893-8968
/code/branches/gameimmersion:8102-8577
/code/branches/gamestate:6430-6572,6621-6661
/code/branches/gamestates2:6594-6745
/code/branches/gametypes:2826-3031
/code/branches/gcc43:1580
/code/branches/gui:1635-1723,2795-2894
/code/branches/hoverHS15:10633-10959
/code/branches/hud:8883-8986
/code/branches/hudHS14:10083-10241
/code/branches/hudelements:6584-6941
/code/branches/hudimprovements:7920-8672
/code/branches/ingamemenu:6000-6023
/code/branches/input:1629-1636
/code/branches/invaders:9694-9896
/code/branches/ipv6:7293-7458
/code/branches/keckslevelHS14:10082-10222
/code/branches/kicklib:7940-8096,8098-8277
/code/branches/kicklib2:8282-8350
/code/branches/largeShip1:9384-9515
/code/branches/lastmanstanding:7479-7644
/code/branches/lastmanstanding3:7903-8175
/code/branches/levelElias:9697-9921
/code/branches/levelKaan:9695-9921
/code/branches/levelMichael:9696-9921
/code/branches/leveljoemeHS14:10087-10223
/code/branches/libraries:5612-5692
/code/branches/libraries2:5703-5737
/code/branches/libs:9668-9674
/code/branches/lod:6586-6911
/code/branches/lodfinal:2372-2411
/code/branches/mac_osx:7789-8128,8135
/code/branches/map:2801-3086,3089
/code/branches/masterserver:7502-7738
/code/branches/masterserverfix:8933-8936
/code/branches/menu:5941-6146,6148,7536-7687
/code/branches/menue:8884-8976
/code/branches/minigame4DHS14:10081-10230
/code/branches/miniprojects:2754-2824
/code/branches/modularships:9994-10071
/code/branches/multiplayerFS15:10324-10611
/code/branches/netp2:2835-2988
/code/branches/netp3:2988-3082
/code/branches/netp6:3214-3302
/code/branches/network:2356
/code/branches/network2:6434-6465
/code/branches/network3:7196-7344
/code/branches/network4:7497-7755
/code/branches/network5:7757-7781
/code/branches/network6:7823-8315
/code/branches/network64:2210-2355
/code/branches/newlevel2012:9033-9244
/code/branches/notifications:7314-7401
/code/branches/objecthierarchy:1911-2085,2100,2110-2169
/code/branches/objecthierarchy2:2171-2479
/code/branches/ois_update:7506-7788
/code/branches/output:8739-8857
/code/branches/overlay:2117-2385
/code/branches/pCuts:9023-9284
/code/branches/particleEffectsHS15:10644-10962
/code/branches/particles:2829-3085
/code/branches/particles2:6050-6106,6109
/code/branches/pch:3113-3194
/code/branches/physics:1912-2055,2107-2439
/code/branches/physics_merge:2436-2457
/code/branches/pickup:8145-8555
/code/branches/pickup2:5942-6405
/code/branches/pickup2012:9029-9189
/code/branches/pickup3:6418-6523
/code/branches/pickup4:6594-6710
/code/branches/pickups:1926-2086,2127,2827-2915
/code/branches/pickups2:2107-2497,2915-3071
/code/branches/pickupsFS14:10000-10259
/code/branches/planetLevelHS15:10637-10966
/code/branches/png2:7262-7263
/code/branches/portals:8087-8455
/code/branches/portals2:8460-8602
/code/branches/ppspickups1:6552-6708
/code/branches/ppspickups2:6527-6532,6554-6709
/code/branches/ppspickups3:6757-6997
/code/branches/ppspickups4:7003-7089
/code/branches/presentation:2369-2652,2654-2660,7736-7786,8500-8705
/code/branches/presentation2:6106-6416,7787-7800
/code/branches/presentation2011:8974-9015
/code/branches/presentation2012:9189-9268
/code/branches/presentation2012merge:9266-9347
/code/branches/presentation3:6913-7162
/code/branches/presentationFS14:10069-10215
/code/branches/presentationFS15:10499
/code/branches/presentationFS15merge:10595-10621
/code/branches/presentationHS12:9481-9525
/code/branches/presentationHS13:9891-9938
/code/branches/presentationHS14merge:10222-10257
/code/branches/questsystem:1894-2088
/code/branches/questsystem2:2107-2259
/code/branches/questsystem5:2776-2905
/code/branches/radarDreiD:9690-9901
/code/branches/releasetodo:7614-7647
/code/branches/resource:3327-3366
/code/branches/resource2:3372-5694
/code/branches/rocket:6523-6950
/code/branches/rocket2:6953-6970
/code/branches/script_trigger:1295-1953,1955
/code/branches/sfxThilo:9691-9917
/code/branches/shipSelection:9038-9206
/code/branches/skybox2:6559-6989
/code/branches/sound:2829-3010
/code/branches/sound2012:9205-9214
/code/branches/sound3:5941-6102
/code/branches/spaceNavigation:9381-9497
/code/branches/spaceboundaries:8085-8457
/code/branches/spaceboundaries2:8460-8613
/code/branches/spacerace:8182-8630
/code/branches/spaceraceTwo:8881-8996
/code/branches/spacestationentry:9699-9905
/code/branches/steering:5949-6091,8140-8595
/code/branches/storymodeHS14:10085-10254
/code/branches/surfaceRace:9028-9199
/code/branches/surfaceraceHS14:10080-10236
/code/branches/testing:9015-9549
/code/branches/tetris:8100-8563
/code/branches/towerdefenseFS15:10283-10614
/code/branches/towerdefenseHS14:10086-10247
/code/branches/turret:9380-9501
/code/branches/turretFS14:9998-10070
/code/branches/tutoriallevel:7827-8370
/code/branches/tutoriallevel2:8370-8452
/code/branches/tutoriallevel3:8453-8636
/code/branches/unity_build:8440-8716
/code/branches/usability:7915-8078
/code/branches/weapon:1925-2094
/code/branches/weapon2:2107-2488
/code/branches/weaponFS15:10302-10615
/code/branches/weapons:2897-3051,8143-8591
/code/branches/weaponsystem:2742-2890
/code/branches/weaponupdateHS14:10084-10237
+ /code/branches/AI_HS15:10640-10832
/code/branches/ParticleEffectsFS15:10309-10612
/code/branches/Racingbot:9388-9513
/code/branches/SciptableControllerFS15:10308-10613
/code/branches/ScriptableController:9999-10075
/code/branches/ai:6592-7033
/code/branches/ai2:8721-8880
/code/branches/bigships:8137-8588
/code/branches/buildsystem:1874-2276,2278-2400
/code/branches/buildsystem2:2506-2658
/code/branches/buildsystem3:2662-2708
/code/branches/campaignHS15:10639-10967
/code/branches/ceguilua:1802-1808
/code/branches/chat:6527-6797
/code/branches/chat2:6836-6910
/code/branches/clangenb:10385-10609
/code/branches/console:5941-6104
/code/branches/consolecommands2:6451-7178
/code/branches/consolecommands3:7178-7283
/code/branches/core3:1572-1739
/code/branches/core4:3221-3224,3227,3234-3238,3242,3244-3250,3252-3254,3256,3259-3261,3264-3265,3268-3275,3277-3278,3280,3284-3285,3287,3289-3294,3305,3309-3310
/code/branches/core5:5768-5928,6009
/code/branches/core6:9552-9666
/code/branches/core7:10328-10623
/code/branches/data_cleanup:7537-7686
/code/branches/doc:7290-7400
/code/branches/dockingsystem:8101-8192
/code/branches/dockingsystem2:8196-8560
/code/branches/dynamicmatch:6584-7030
/code/branches/environment3:8887-8975
/code/branches/explosionChunksHS15:10641-10961
/code/branches/fabienHS15:10685-10960
/code/branches/formation:8885-8991
/code/branches/formationFS15:10320-10610
/code/branches/formationupdate:9580-9624
/code/branches/fps:6591-7072
/code/branches/gamecontent:8893-8968
/code/branches/gameimmersion:8102-8577
/code/branches/gamestate:6430-6572,6621-6661
/code/branches/gamestates2:6594-6745
/code/branches/gametypes:2826-3031
/code/branches/gcc43:1580
/code/branches/gui:1635-1723,2795-2894
/code/branches/hoverHS15:10633-10959
/code/branches/hud:8883-8986
/code/branches/hudHS14:10083-10241
/code/branches/hudelements:6584-6941
/code/branches/hudimprovements:7920-8672
/code/branches/ingamemenu:6000-6023
/code/branches/input:1629-1636
/code/branches/invaders:9694-9896
/code/branches/ipv6:7293-7458
/code/branches/keckslevelHS14:10082-10222
/code/branches/kicklib:7940-8096,8098-8277
/code/branches/kicklib2:8282-8350
/code/branches/largeShip1:9384-9515
/code/branches/lastmanstanding:7479-7644
/code/branches/lastmanstanding3:7903-8175
/code/branches/levelElias:9697-9921
/code/branches/levelKaan:9695-9921
/code/branches/levelMichael:9696-9921
/code/branches/leveljoemeHS14:10087-10223
/code/branches/libraries:5612-5692
/code/branches/libraries2:5703-5737
/code/branches/libs:9668-9674
/code/branches/lod:6586-6911
/code/branches/lodfinal:2372-2411
/code/branches/mac_osx:7789-8128,8135
/code/branches/map:2801-3086,3089
/code/branches/masterserver:7502-7738
/code/branches/masterserverfix:8933-8936
/code/branches/menu:5941-6146,6148,7536-7687
/code/branches/menue:8884-8976
/code/branches/minigame4DHS14:10081-10230
/code/branches/miniprojects:2754-2824
/code/branches/modularships:9994-10071
/code/branches/multiplayerFS15:10324-10611
/code/branches/netp2:2835-2988
/code/branches/netp3:2988-3082
/code/branches/netp6:3214-3302
/code/branches/network:2356
/code/branches/network2:6434-6465
/code/branches/network3:7196-7344
/code/branches/network4:7497-7755
/code/branches/network5:7757-7781
/code/branches/network6:7823-8315
/code/branches/network64:2210-2355
/code/branches/newlevel2012:9033-9244
/code/branches/notifications:7314-7401
/code/branches/objecthierarchy:1911-2085,2100,2110-2169
/code/branches/objecthierarchy2:2171-2479
/code/branches/ois_update:7506-7788
/code/branches/output:8739-8857
/code/branches/overlay:2117-2385
/code/branches/pCuts:9023-9284
/code/branches/particleEffectsHS15:10644-10962
/code/branches/particles:2829-3085
/code/branches/particles2:6050-6106,6109
/code/branches/pch:3113-3194
/code/branches/physics:1912-2055,2107-2439
/code/branches/physics_merge:2436-2457
/code/branches/pickup:8145-8555
/code/branches/pickup2:5942-6405
/code/branches/pickup2012:9029-9189
/code/branches/pickup3:6418-6523
/code/branches/pickup4:6594-6710
/code/branches/pickups:1926-2086,2127,2827-2915
/code/branches/pickups2:2107-2497,2915-3071
/code/branches/pickupsFS14:10000-10259
/code/branches/planetLevelHS15:10637-10966
/code/branches/png2:7262-7263
/code/branches/portals:8087-8455
/code/branches/portals2:8460-8602
/code/branches/ppspickups1:6552-6708
/code/branches/ppspickups2:6527-6532,6554-6709
/code/branches/ppspickups3:6757-6997
/code/branches/ppspickups4:7003-7089
/code/branches/presentation:2369-2652,2654-2660,7736-7786,8500-8705
/code/branches/presentation2:6106-6416,7787-7800
/code/branches/presentation2011:8974-9015
/code/branches/presentation2012:9189-9268
/code/branches/presentation2012merge:9266-9347
/code/branches/presentation3:6913-7162
/code/branches/presentationFS14:10069-10215
/code/branches/presentationFS15:10499
/code/branches/presentationFS15merge:10595-10621
/code/branches/presentationHS12:9481-9525
/code/branches/presentationHS13:9891-9938
/code/branches/presentationHS14merge:10222-10257
/code/branches/questsystem:1894-2088
/code/branches/questsystem2:2107-2259
/code/branches/questsystem5:2776-2905
/code/branches/radarDreiD:9690-9901
/code/branches/releasetodo:7614-7647
/code/branches/resource:3327-3366
/code/branches/resource2:3372-5694
/code/branches/rocket:6523-6950
/code/branches/rocket2:6953-6970
/code/branches/script_trigger:1295-1953,1955
/code/branches/sfxThilo:9691-9917
/code/branches/shipSelection:9038-9206
/code/branches/skybox2:6559-6989
/code/branches/sound:2829-3010
/code/branches/sound2012:9205-9214
/code/branches/sound3:5941-6102
/code/branches/spaceNavigation:9381-9497
/code/branches/spaceboundaries:8085-8457
/code/branches/spaceboundaries2:8460-8613
/code/branches/spacerace:8182-8630
/code/branches/spaceraceTwo:8881-8996
/code/branches/spacestationentry:9699-9905
/code/branches/steering:5949-6091,8140-8595
/code/branches/storymodeHS14:10085-10254
/code/branches/surfaceRace:9028-9199
/code/branches/surfaceraceHS14:10080-10236
/code/branches/testing:9015-9549
/code/branches/tetris:8100-8563
/code/branches/towerdefenseFS15:10283-10614
/code/branches/towerdefenseHS14:10086-10247
/code/branches/turret:9380-9501
/code/branches/turretFS14:9998-10070
/code/branches/tutoriallevel:7827-8370
/code/branches/tutoriallevel2:8370-8452
/code/branches/tutoriallevel3:8453-8636
/code/branches/unity_build:8440-8716
/code/branches/usability:7915-8078
/code/branches/weapon:1925-2094
/code/branches/weapon2:2107-2488
/code/branches/weaponFS15:10302-10615
/code/branches/weapons:2897-3051,8143-8591
/code/branches/weaponsystem:2742-2890
/code/branches/weaponupdateHS14:10084-10237
Modified: code/branches/presentationHS15/data/defaultConfig/orxonox.ini
===================================================================
--- code/branches/presentationHS15/data/defaultConfig/orxonox.ini 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/data/defaultConfig/orxonox.ini 2015-12-11 14:26:20 UTC (rev 10970)
@@ -3,3 +3,8 @@
campaignMissions_[1] = "fightInOurBack.oxw"
campaignMissions_[2] = "pirateAttack.oxw"
campaignMissions_[3] = "iJohnVane_TriptoArea51.oxw"
+campaignMissions_[4] = "iiJohnVane_Area51UnderFire.oxw"
+campaignMissions_[5] = "iiiJohnVane_EscapeTheBastards.oxw"
+campaignMissions_[6] = "expeditionSector.oxw"
+campaignMissions_[7] = "shuttleAttack.oxw"
+campaignMissions_[8] = "shuttleRetaliation.oxw"
Modified: code/branches/presentationHS15/data/gui/layouts/CampaignMenu.layout
===================================================================
--- code/branches/presentationHS15/data/gui/layouts/CampaignMenu.layout 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/data/gui/layouts/CampaignMenu.layout 2015-12-11 14:26:20 UTC (rev 10970)
@@ -7,41 +7,83 @@
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
<Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1.0,0},{1.0,0}}" />
<Property Name="BackgroundEnabled" Value="False" />
- <Window Type="MenuWidgets/Button" Name="orxonox/MissionOneButton" >
- <Property Name="Text" Value="Mission 1" />
+ <Window Type="MenuWidgets/Button" Name="orxonox/Mission1Button" >
+ <Property Name="Text" Value="Mission One" />
<Property Name="Visible" Value="False"/>
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
- <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.2875,0},{0.6,0},{0.3375,0}}" />
- <Event Name="Clicked" Function="CampaignMenu.MissionOneButton_clicked"/>
+ <Property Name="UnifiedAreaRect" Value="{{0.35,0},{0.1,0},{0.65,0},{0.15,0}}" />
+ <Event Name="Clicked" Function="CampaignMenu.Mission1Button_clicked"/>
</Window>
- <Window Type="MenuWidgets/Button" Name="orxonox/MissionTwoButton" >
- <Property Name="Text" Value="Mission 2" />
+ <Window Type="MenuWidgets/Button" Name="orxonox/Mission2Button" >
+ <Property Name="Text" Value="Fight in our Back" />
<Property Name="Visible" Value="False"/>
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
- <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.3625,0},{0.6,0},{0.4125,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.35,0},{0.18,0},{0.65,0},{0.23,0}}" />
<Property Name="Disabled" Value="True" />
- <Event Name="Clicked" Function="CampaignMenu.MissionTwoButton_clicked"/>
+ <Event Name="Clicked" Function="CampaignMenu.Mission2Button_clicked"/>
</Window>
- <Window Type="MenuWidgets/Button" Name="orxonox/MissionThreeButton" >
- <Property Name="Text" Value="Mission 3" />
+ <Window Type="MenuWidgets/Button" Name="orxonox/Mission3Button" >
+ <Property Name="Text" Value="Pirate Attack" />
<Property Name="Visible" Value="False"/>
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
- <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.4375,0},{0.6,0},{0.4875,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.35,0},{0.26,0},{0.65,0},{0.31,0}}" />
<Property Name="Disabled" Value="True" />
- <Event Name="Clicked" Function="CampaignMenu.MissionThreeButton_clicked"/>
+ <Event Name="Clicked" Function="CampaignMenu.Mission3Button_clicked"/>
</Window>
- <Window Type="MenuWidgets/Button" Name="orxonox/MissionFourButton" >
- <Property Name="Text" Value="Mission 4" />
+ <Window Type="MenuWidgets/Button" Name="orxonox/Mission4Button" >
+ <Property Name="Text" Value="Trip to Area 51" />
<Property Name="Visible" Value="False"/>
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
- <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.5125,0},{0.6,0},{0.5625,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.35,0},{0.34,0},{0.65,0},{0.39,0}}" />
<Property Name="Disabled" Value="True" />
- <Event Name="Clicked" Function="CampaignMenu.MissionFourButton_clicked"/>
+ <Event Name="Clicked" Function="CampaignMenu.Mission4Button_clicked"/>
</Window>
+ <Window Type="MenuWidgets/Button" Name="orxonox/Mission5Button" >
+ <Property Name="Text" Value="Area 51 under Fire" />
+ <Property Name="Visible" Value="False"/>
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.35,0},{0.42,0},{0.65,0},{0.47,0}}" />
+ <Property Name="Disabled" Value="True" />
+ <Event Name="Clicked" Function="CampaignMenu.Mission5Button_clicked"/>
+ </Window>
+ <Window Type="MenuWidgets/Button" Name="orxonox/Mission6Button" >
+ <Property Name="Text" Value="Escape the Bastards" />
+ <Property Name="Visible" Value="False"/>
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.35,0},{0.50,0},{0.65,0},{0.55,0}}" />
+ <Property Name="Disabled" Value="True" />
+ <Event Name="Clicked" Function="CampaignMenu.Mission6Button_clicked"/>
+ </Window>
+ <Window Type="MenuWidgets/Button" Name="orxonox/Mission7Button" >
+ <Property Name="Text" Value="Expedition to Sector 5C" />
+ <Property Name="Visible" Value="False"/>
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.35,0},{0.58,0},{0.65,0},{0.63,0}}" />
+ <Property Name="Disabled" Value="True" />
+ <Event Name="Clicked" Function="CampaignMenu.Mission7Button_clicked"/>
+ </Window>
+ <Window Type="MenuWidgets/Button" Name="orxonox/Mission8Button" >
+ <Property Name="Text" Value="Shuttle under Attack" />
+ <Property Name="Visible" Value="False"/>
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.35,0},{0.66,0},{0.65,0},{0.71,0}}" />
+ <Property Name="Disabled" Value="True" />
+ <Event Name="Clicked" Function="CampaignMenu.Mission8Button_clicked"/>
+ </Window>
+ <Window Type="MenuWidgets/Button" Name="orxonox/Mission9Button" >
+ <Property Name="Text" Value="Retaliation" />
+ <Property Name="Visible" Value="False"/>
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.35,0},{0.74,0},{0.65,0},{0.79,0}}" />
+ <Property Name="Disabled" Value="True" />
+ <Event Name="Clicked" Function="CampaignMenu.Mission9Button_clicked"/>
+ </Window>
+
+
<Window Type="MenuWidgets/Button" Name="orxonox/CampaignMenuBackButton" >
<Property Name="Text" Value="Back" />
<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
- <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.8,0},{0.6,0},{0.85,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.35,0},{0.85,0},{0.65,0},{0.9,0}}" />
<Event Name="Clicked" Function="CampaignMenu.CampaignMenuBackButton_clicked"/>
</Window>
<Window Type="MenuWidgets/StaticText" Name="orxonox/CampaignMenuCongratulation" >
Modified: code/branches/presentationHS15/data/gui/scripts/CampaignMenu.lua
===================================================================
--- code/branches/presentationHS15/data/gui/scripts/CampaignMenu.lua 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/data/gui/scripts/CampaignMenu.lua 2015-12-11 14:26:20 UTC (rev 10970)
@@ -7,11 +7,17 @@
end
function P.updateButtons()
- P.updateButton(0, winMgr:getWindow("orxonox/MissionOneButton"))
- P.updateButton(1, winMgr:getWindow("orxonox/MissionTwoButton"))
- P.updateButton(2, winMgr:getWindow("orxonox/MissionThreeButton"))
- P.updateButton(3, winMgr:getWindow("orxonox/MissionFourButton"))
+ P.updateButton(0, winMgr:getWindow("orxonox/Mission1Button"))
+ P.updateButton(1, winMgr:getWindow("orxonox/Mission2Button"))
+ P.updateButton(2, winMgr:getWindow("orxonox/Mission3Button"))
+ P.updateButton(3, winMgr:getWindow("orxonox/Mission4Button"))
+ P.updateButton(4, winMgr:getWindow("orxonox/Mission5Button"))
+ P.updateButton(5, winMgr:getWindow("orxonox/Mission6Button"))
+ P.updateButton(6, winMgr:getWindow("orxonox/Mission7Button"))
+ P.updateButton(7, winMgr:getWindow("orxonox/Mission8Button"))
+ P.updateButton(8, winMgr:getWindow("orxonox/Mission9Button"))
+
if (P.getIndexOfLastFinishedMission() == orxonox.LevelManager:getInstance():getNumberOfCampaignMissions() - 1) then
local label = winMgr:getWindow("orxonox/CampaignMenuCongratulation")
label:setProperty("Visible","True")
@@ -53,22 +59,42 @@
return -1
end
-function P.MissionOneButton_clicked(e)
+function P.Mission1Button_clicked(e)
P.loadLevel(P.FindLevel(0))
end
-function P.MissionTwoButton_clicked(e)
+function P.Mission2Button_clicked(e)
P.loadLevel(P.FindLevel(1))
end
-function P.MissionThreeButton_clicked(e)
+function P.Mission3Button_clicked(e)
P.loadLevel(P.FindLevel(2))
end
-function P.MissionFourButton_clicked(e)
+function P.Mission4Button_clicked(e)
P.loadLevel(P.FindLevel(3))
end
+function P.Mission5Button_clicked(e)
+ P.loadLevel(P.FindLevel(4))
+end
+
+function P.Mission6Button_clicked(e)
+ P.loadLevel(P.FindLevel(5))
+end
+
+function P.Mission7Button_clicked(e)
+ P.loadLevel(P.FindLevel(6))
+end
+
+function P.Mission8Button_clicked(e)
+ P.loadLevel(P.FindLevel(7))
+end
+
+function P.Mission9Button_clicked(e)
+ P.loadLevel(P.FindLevel(8))
+end
+
function P.loadLevel(level)
orxonox.execute("startGame " .. level:getXMLFilename())
hideAllMenuSheets()
Copied: code/branches/presentationHS15/data/levels/AITest.oxw (from rev 10967, code/branches/campaignHS15/data/levels/AITest.oxw)
===================================================================
--- code/branches/presentationHS15/data/levels/AITest.oxw (rev 0)
+++ code/branches/presentationHS15/data/levels/AITest.oxw 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,351 @@
+<LevelInfo
+ name = "New AI testing level"
+ description = "A level with two opposing new AI teams"
+ tags = "test"
+ screenshot = "emptylevel.png"
+/>
+
+<?lua
+ include("stats.oxo")
+ include("HUDTemplates3.oxo")
+ include("templates/lodInformation.oxt")
+?>
+
+<?lua
+ include("templates/spaceshipAssff.oxt")
+ include("templates/spaceshipPirate.oxt")
+ include("templates/spaceshipEscort.oxt")
+ include("templates/spaceshipRing.oxt")
+ include("templates/spaceshipSwallow.oxt")
+ include("templates/pickupRepresentationTemplates.oxt")
+?>
+
+
+<Level>
+ <templates>
+ <Template link=lodtemplate_default />
+ </templates>
+ <?lua include("includes/notifications.oxi") ?>
+
+ <Scene
+ ambientlight = "0.8, 0.8, 0.8"
+ skybox = "Orxonox/Starbox"
+ >
+ <?lua
+ include("includes/pickups.oxi")
+ ?>
+ <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0"/>
+ <TeamSpawnPoint team=0 position="2000, 2000, 2000" lookat="1,1,-1" spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+ <Pawn position = "100000, 100000, 100000">
+ <controller>
+ <MasterController>
+ </MasterController>
+ </controller>
+ </Pawn>
+<!--
+ <PickupSpawner pickup=largedamageboostpickup position="0,0,0" triggerDistance="20" respawnTime="30" maxSpawnedItems="10" />
+<PickupSpawner pickup=crazyhealthpickup position="0,0,0" triggerDistance="50" respawnTime="30" maxSpawnedItems="10" />
+<PickupSpawner pickup=hugeshieldpickup position="4000,4500, 4500" triggerDistance="10" respawnTime="5" maxSpawnedItems="10" />
+<PickupSpawner pickup=smalljumppickup position="6500,6500, 6000" triggerDistance="20" respawnTime="10" maxSpawnedItems="99" />
+<PickupSpawner pickup=largedamageboostpickup position="9500,9500, 9500" triggerDistance="20" respawnTime="30" maxSpawnedItems="10" />
+<PickupSpawner pickup=largedamageboostpickup position="13000,13000,13000" triggerDistance="10" respawnTime="30" maxSpawnedItems="10" />
+ -->
+<!-- HERE STARTS DEMO FOR THE "WAYPOINTS" -->
+ <!--
+ <SpaceShip position="-1500, -1500, -1500" lookat="0,0,0" team=0 name="ss1">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=1 formationMode="finger4">
+ <actionpoints>
+ <Model mesh="cube.mesh" scale=8 position=" 0,2000,-600" />
+ <Model mesh="cube.mesh" scale=8 position=" 0,2000,-1000" />
+ <Model mesh="cube.mesh" scale=8 position="400,2000,-1000" />
+ <Model mesh="cube.mesh" scale=8 position="400,2000,-600" />
+ </actionpoints>
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+ -->
+ <!-- those two are same -->
+
+ <!--
+ <Model mesh="cube.mesh" scale=8 position=" 0,2000,-600" />
+ <Model mesh="cube.mesh" scale=8 position=" 0,2000,-1000" />
+ <Model mesh="cube.mesh" scale=8 position="400,2000,-1000" />
+ <Model mesh="cube.mesh" scale=8 position="400,2000,-600" />
+ <SpaceShip position="-1500, 1500, -1000" lookat="0,0,0" team=0 name="ss1">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=0 formationMode="finger4">
+ <actionpoints>
+ <Actionpoint position=" 0,2000,-600" action="FLY" loopStart=true/>
+ <Actionpoint position=" 0,2000,-1000" action="FLY" />
+ <Actionpoint position="400,2000,-1000" action="FLY" />
+ <Actionpoint position="400,2000,-600" action="FLY" loopEnd=true />
+ </actionpoints>
+ </DivisionController>
+ </controller>
+ </SpaceShip> -->
+
+<!-- HERE ENDS DEMO FOR THE "WAYPOINTS" -->
+
+<!-- HERE STARTS DEMO FOR THE ACTIONPOINTS.
+P.S. Never set protectMe in the first actionpoint: if human didn't spawn, that actionpoint will be skipped -->
+ <!--
+ <Model mesh="cube.mesh" scale=8 position="0,0,0" />
+
+ <SpaceShip position="-2000, 1500, -1000" lookat="0,0,0" team=0 name="ss2">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=0 formationMode="finger4">
+ <actionpoints>
+ <Actionpoint position="0,0,0" action="FLY" />
+ <Actionpoint position="-1000,750,-500" action="ATTACK" attack="attack" />
+ <Actionpoint position="-1000,750,-500" action="PROTECt" protectMe=true />
+ <Actionpoint position="-1000,750,-500" action="PROTECt" protect="protect" />
+ <Actionpoint position="-1000,750,-500" action="FIGHTALL" />
+ </actionpoints>
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="-2000, 1900, -1000" lookat="0,0,0" team=0>
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <SectionController team=0>
+ </SectionController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="-2000, 2100, -1000" lookat="0,0,0" team=0>
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <WingmanController team=0>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="-2000, 2400, -1000" lookat="0,0,0" team=0>
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <WingmanController team=0>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="0, 0, 0" lookat="0,0,0" team=2 name="ss4">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ </SpaceShip>
+ <SpaceShip position="3000, 1000, 2000" lookat="0,0,0" team=2 name="attack">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ </SpaceShip>
+ <SpaceShip position="-500, -300, -300" lookat="0,0,0" team=0 name="protect">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ </SpaceShip>
+ -->
+
+<!-- HERE ENDS DEMO FOR THE ACTIONPOINTS -->
+<!-- HERE STARTS DEMO FOR FIGHTING -->
+ <!--
+
+ <SpaceShip position="-4000, 1500, -1000" lookat="0,0,0" team=0 name="d1sd1">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=0 formationMode="WALL">
+
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="-4000, 1900, -1000" lookat="0,0,0" team=0 name="d1ss1">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <SectionController team=0>
+ </SectionController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="-4000, 2100, -1000" lookat="0,0,0" team=0 name="d1sw1">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <WingmanController team=0>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="-4000, 2400, -1000" lookat="0,0,0" team=0 name="d1sw2">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <WingmanController team=0>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip position="2000, -1500, 1000" lookat="0,0,0" team=1 name="d2sd1">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=1 formationMode="DIAMOND">
+
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="2000, -1900, 1000" lookat="0,0,0" team=1 name="d2ss1">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <SectionController team=1>
+ </SectionController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="2000, -2100, 1000" lookat="0,0,0" team=1 name="d2sw1">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <WingmanController team=1>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="2000, -2400, 1000" lookat="0,0,0" team=1 name="d2sw2">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <WingmanController team=1>
+ </WingmanController>
+ </controller>
+ </SpaceShip> -->
+
+<!-- HERE ENDS DEMO FOR FIGHTING -->
+<!-- HERE STARTS DEMO FOR FORMATIONS -->
+
+ <Model mesh="cube.mesh" scale=8 position=" 0,2000, 0" />
+ <Model mesh="cube.mesh" scale=8 position=" 0,2000,-2000" />
+ <Model mesh="cube.mesh" scale=8 position="2000,2000,-2000" />
+ <Model mesh="cube.mesh" scale=8 position="2000,2000, 0" />
+
+ <SpaceShip position="-1500, 1500, -1000" lookat="0,0,0" team=0 name="ss1">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=0 formationMode="diamond" spread=100>
+ <actionpoints>
+ <Actionpoint position=" 0,2000, 0" action="FLY" loopStart=true/>
+ <Actionpoint position=" 0,2000,-2000" action="FLY" />
+ <Actionpoint position="2000,2000,-2000" action="FLY" />
+ <Actionpoint position="2000,2000, 0" action="FLY" loopEnd=true />
+ </actionpoints>
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip position="-2000, 1900, -1000" lookat="0,0,0" team=0>
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <SectionController team=0>
+ </SectionController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="-2000, 2100, -1000" lookat="0,0,0" team=0>
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <WingmanController team=0>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="-2000, 2400, -1000" lookat="0,0,0" team=0>
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <WingmanController team=0>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+
+<!-- HERE ENDS DEMO FOR FORMATIONS -->
+ <!-- 1 division is roughly equal to 6 AIControllers--!>
+<!--
+ <SpaceShip position="2000, -1500, 1000" lookat="0,0,0" team=1 >
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=1 formationMode="WALL">
+
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="2000, -1900, 1000" lookat="0,0,0" team=1>
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <SectionController team=1>
+ </SectionController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="2000, -2100, 1000" lookat="0,0,0" team=1>
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <WingmanController team=1>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+ <SpaceShip position="2000, -2400, 1000" lookat="0,0,0" team=1>
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <WingmanController team=1>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+
+ <?lua
+ for i = 0, 5, 1 do
+ ?>
+ <SpaceShip position="<?lua print(7000) ?>,<?lua print(i*500) ?>,<?lua print(0) ?>" team=2>
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <AIController team=2 />
+ </controller>
+ </SpaceShip>
+ <?lua end ?> -->
+
+
+ </Scene>
+</Level>
+
Copied: code/branches/presentationHS15/data/levels/expeditionSector.oxw (from rev 10967, code/branches/campaignHS15/data/levels/expeditionSector.oxw)
===================================================================
--- code/branches/presentationHS15/data/levels/expeditionSector.oxw (rev 0)
+++ code/branches/presentationHS15/data/levels/expeditionSector.oxw 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,858 @@
+<LevelInfo
+ name = "Expedition to Sector 5C"
+ description = "Commander, our scientists are reporting strange binary radio signals from a yet unexplored and thought to be uninhabited region, sector 5C. Explore the sector and get to the bottom of these messages!"
+ tags = "mission"
+ screenshot = "expeditionSector.png"
+/>
+
+<?lua
+ include("stats.oxo")
+ include("HUDTemplates3.oxo")
+ include("templates/lodInformation.oxt")
+
+ include("templates/spaceshipAssff.oxt")
+ include("templates/spaceshipPirate.oxt")
+ include("templates/spaceshipEscort.oxt")
+ include("templates/spaceshipShuttle.oxt")
+ include("templates/FPS.oxt")
+ include("templates/pickupRepresentationTemplates.oxt")
+?>
+
+<Level gametype = "Mission">
+ <templates>
+ <Template link="lodtemplate_default" />
+ </templates>
+
+ <?lua include("includes/notifications.oxi") ?>
+
+ <NotificationQueueCEGUI
+ name="narrative"
+ targets="simpleNotification"
+ size=3
+ displayTime=3.9
+ position="0.15, 0, 0.1, 0"
+ fontSize="15"
+ fontColor="0.3, 1, 0.2, 0.8"
+ alignment="HorzCentred"
+ displaySize="0.7, 0, 0, 0"
+ />
+
+ <!-- GLOBAL LUA VARIABLES -->
+ <?lua
+
+ --[[ Coordinates in (y,z,x). NOTE: Indexing starts at 1 in lua! Don“t forget to adapt the for loops, too! ]]--
+ cCenter = {0, 0, 0}
+ cSpawn = {-50, 0, 0}
+ cSector = {-15000, -5500, -9000}
+ cSectorEntry = {-4710, -5500, -2826}
+ cPathToEntry = {{0, -2000, 0}}
+ cBeacon = {-6500, -5500, -4400}
+
+ radSector = 12000
+
+ cStationA = {1400, 400, -800}
+ cNewShip = {1000, 250, -350}
+
+ cPlanet1 = {20000, 0, 29000}
+ cPlanet2 = {-22000, 0, -29000}
+
+ cEnemyBasePlanet = {-20000, -5500, -8000}
+
+ cEnemyBaseStation1 = {-12500, -4500, -3500}
+
+ cField1 = {-5000, -4000, -3000}
+ cField2 = {4000, 2000, 4500}
+
+ --[[ Function to print Coordinates. Quotes not included! ]]--
+ function printC(coord)
+ print(coord[1] .. [[,]] .. coord[2] .. [[,]] .. coord[3])
+ end
+
+ --[[ Function to add Coordinates.]]--
+ function addC(coord1, coord2)
+ return {coord1[1]+coord2[1], coord1[2]+coord2[2], coord1[3]+coord2[3]}
+ end
+ ?>
+
+ <Scene
+ ambientlight = "0.8, 0.8, 0.8"
+ skybox = "Orxonox/skyBoxMoreNebula"
+ hasPhysics = true
+ >
+
+ <SpawnPoint name="playerSpawn" team=0 position="<?lua printC(cSpawn) ?>" lookat="<?lua printC(cCenter) ?>" spawnclass=SpaceShip pawndesign=spaceshipescort />
+
+ <WorldAmbientSound source="Earth.ogg" looping="true" playOnLoad="true" />
+
+ <Light type=directional position="<?lua printC(cCenter) ?>" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0"/>
+
+ <!--QUEST DEFINITIONS-->
+
+ <GlobalQuest id="quest1">
+ <QuestDescription title="Get the scout ship" description="We received some extraterrestial binary radio signals from Sector 5C! We'd like you to get to the outer base in sector 4A and get a scout ship to explore the sector!" failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <complete-effects>
+ <AddQuest questId="quest2" />
+ </complete-effects>
+ </GlobalQuest>
+
+ <GlobalQuest id="quest2">
+ <QuestDescription title="Explore the sector" description="Now then, Commander, fly over there to check out if life can be found in what we believed it to be an inhabitated region in space. We have marked 5B with red lights so you can easily find it." failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <subquests>
+ <GlobalQuest id="quest2.1">
+ <QuestDescription title="> Get to the Field Source" description="We percieve a large magnetic field source at a certain spot in the sector. You should check it out! We have marked it with a blue light." failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <complete-effects>
+ <AddQuest questId="quest2.2" />
+ </complete-effects>
+ </GlobalQuest>
+ <GlobalQuest id="quest2.2">
+ <QuestDescription title="> Fight your way out" description="Oh no... this cannot be happening! We discovered an alien race, and it does not seem to be interested in peace. In fact, they seem to be planning an attack! You must get out of the hot zone. Fight if necessary!" failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <complete-effects>
+ <AddQuest questId="quest3" />
+ </complete-effects>
+ </GlobalQuest>
+ </subquests>
+ </GlobalQuest>
+
+ <GlobalQuest id="quest3">
+ <QuestDescription title="Get back to 4A" description="You made it out in one piece. Now report to base 4A to warn the others!" failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ </GlobalQuest>
+
+ <!--EVENTS AND TRIGGERS
+ Usable events and triggers:
+ spawntrigger
+ dockA
+ reachedSector
+ reachedEnemyStation
+ fightEnd
+ backToA
+
+ BASE-STORY-LINE:
+ We receive a message from commander (SimpleNotification -> SpawnTrigger) about alien radio activity in a nearby sector and are asked to change our spaceship
+ QUEST1: Dock to Station and get better Spaceship
+ TRIGGER: Docked to Station
+ EVENT: Change Spaceship and Sector 5C becomes visilbe
+
+ We are asked to go to the sector and explore it
+ QUEST2.1: Go to Sector 5C and see what you can find there
+ TRIGGER: Distance Trigger at enemy spacestation, with a rather large radius
+ EVENT: The 25 Enemies and there SpaceStation become visible, the planet should stay invisible; the patroling enemies on your way back become visible as well.
+
+ On your way back you discover the patroling enemy spaceships, they attack you, but you must survive and report to your commander about an possible upcoming attack from the aliens
+ QUEST2.2: Destroy the patroling spaceships, spare no one
+ TRIGGER: -------- The patroling spaceships should triggered bythemselves?
+ EVENT: After destroying all 5 enemy ships, you can return to your base and safety, the Distancetrigger for next quest is activated
+ FAIL: You fail if you die here
+
+ After destroying the enemy ships, you make it bake to your station in time to report about the hord of enemies you saw and start preparing for the upcoming fight!
+ QUEST3: Go back to spacestation
+ TRIGGER: Distancetrigger i suppose?
+ EVENT: You win this level, and the main level is unlocked.
+ -->
+
+ <EventMultiTrigger name="spawntrigger">
+ <events>
+ <trigger>
+ <EventListener event="playerSpawn" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <!-- HACK: just waited out 3sec for animation. Cannot link an event to the COMPLETION of a dock. How is this not possible?? -->
+ <EventMultiTrigger name="dockedA" activations="1" stayactive="true" delay=3>
+ <events>
+ <trigger>
+ <EventListener event="dockA" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <DistanceTrigger name="reachedSector" position="<?lua printC(cSector) ?>" distance="<?lua print(radSector) ?>" target="SpaceShip" beaconMode="identify" targetname="newSpaceShip" stayactive=true />
+
+ <DistanceTrigger name="reachedEnemyStation" position="<?lua printC(cEnemyBaseStation1) ?>" distance="5000" target="SpaceShip" beaconMode="identify" targetname="newSpaceShip" stayactive=true />
+
+ <!-- Recursive helper function for the fightEnd event -->
+ <?lua
+ function enemyTriggerRecursor(i)
+ if i > 0 then
+ return [[
+ <EventTrigger name=killedEnemy]] .. i .. [[ activations=1 stayactive=true delay=0.1>
+ <events>
+ <trigger>
+ <EventListener event=enemy />
+ </trigger>
+ </events>
+ ]] .. enemyTriggerRecursor(i-1) .. [[
+ </EventTrigger>
+ ]]
+ else return ""
+ end
+ end
+ ?>
+ <!-- Actual Event for the enemies. -->
+ <?lua print(enemyTriggerRecursor(5)) ?>
+ <EventMultiTrigger name="fightEnd" delay=0.1 stayactive=true>
+ <events>
+ <trigger>
+ <EventListener event="killedEnemy5" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <DistanceTrigger active=false name="closeToPatrol" position="<?lua printC(cStationA) ?>" distance="6000" target="SpaceShip" beaconMode="identify" targetname="newSpaceShip" stayactive=true >
+ <events>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ </DistanceTrigger>
+
+ <DistanceTrigger active=false name="backToA" position="<?lua printC(cStationA) ?>" distance="600" target="SpaceShip" beaconMode="identify" targetname="newSpaceShip" stayactive=true >
+ <events>
+ <activity>
+ <EventListener event="fightEnd" />
+ </activity>
+ </events>
+ </DistanceTrigger>
+
+ <Script code="Mission endMission true" onLoad="false">
+ <events>
+ <trigger>
+ <EventListener event="backToA" />
+ </trigger>
+ </events>
+ </Script>
+
+ <DistanceTrigger invert=true active=false name="hasDied" position="<?lua printC(cSector) ?>" distance="100000" target="SpaceShip" beaconMode="identify" targetname="newSpaceShip" stayactive=true >
+ <events>
+ <activity>
+ <EventListener event="reachedSector" />
+ </activity>
+ </events>
+ </DistanceTrigger>
+
+ <Script code="Mission endMission fail" onLoad="false">
+ <events>
+ <trigger>
+ <EventListener event="hasDied" />
+ </trigger>
+ </events>
+ </Script>
+
+ <!--QUEST EFFECT BEACONS -->
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <AddQuest questId="quest1" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="spawntrigger" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest1" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="dockedA" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <AddQuest questId="quest2.1" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="reachedSector" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest2.1" />
+ <AddQuest questId="quest2.2" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="reachedEnemyStation" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest2.2" />
+ <CompleteQuest questId="quest2" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="fightEnd" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <!--NOTIFICATIONS -->
+
+ <SimpleNotification broadcast="true" message="Welcome, Commander.">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=4 >
+ <events>
+ <trigger>
+ <EventListener event="spawntrigger" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="We've picked up strange radio Signals from Sector 5B!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=8 >
+ <events>
+ <trigger>
+ <EventListener event="spawntrigger" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Please dock to the outer base and get into the scout ship!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=12 >
+ <events>
+ <trigger>
+ <EventListener event="spawntrigger" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="We have marked the sector in red Lights. Enter it!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=0 >
+ <events>
+ <trigger>
+ <EventListener event="dockedA" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Huh? Something's emanating a strong field... We marked it in blue.">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=0 >
+ <events>
+ <trigger>
+ <EventListener event="reachedSector" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Woah! What the hell? We made alien contact!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=0 >
+ <events>
+ <trigger>
+ <EventListener event="reachedEnemyStation" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="It looks like they are getting ready to attack someone...">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=4 >
+ <events>
+ <trigger>
+ <EventListener event="reachedEnemyStation" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="It must be us! Commander, get back to the base and report!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=8 >
+ <events>
+ <trigger>
+ <EventListener event="reachedEnemyStation" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Oh no! A patrol! When did it get here?!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=0 >
+ <events>
+ <trigger>
+ <EventListener event="closeToPatrol" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Phew, that was close. Now get back here!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=0 >
+ <events>
+ <trigger>
+ <EventListener event="fightEnd" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <!--STATIONS -->
+
+ <Template name="station">
+ <Pawn mass=10000000 collisionType=dynamic friction=0.01>
+ <attached>
+ <Model mesh="HydroHarvester.mesh" position="0,0,0" scale=50 />
+ <DistanceTriggerBeacon name="NPC" />
+ </attached>
+ <collisionShapes>
+ <BoxCollisionShape position="-560,0,0" halfExtents="115,100,245" /><!-- Three lower boxes -->
+ <BoxCollisionShape position="290,0,-480" halfExtents="115,100,245" yaw=-120 />
+ <BoxCollisionShape position="290,0,480" halfExtents="115,100,245" yaw=-240 />
+ <BoxCollisionShape position="-280,0,0" halfExtents="163,50,50" /><!-- Three lower connections -->
+ <BoxCollisionShape position="140,0,-240" halfExtents="163,50,50" yaw=-120 />
+ <BoxCollisionShape position="140,0,240" halfExtents="163,50,50" yaw=-240 />
+ <BoxCollisionShape position="0,530,0" halfExtents="172,52,298" /><!-- Upper Tower -->
+ <BoxCollisionShape position="0,530,0" halfExtents="172,52,298" yaw=-120 />
+ <BoxCollisionShape position="0,530,0" halfExtents="172,52,298" yaw=-240 />
+ <BoxCollisionShape position="0,400,0" halfExtents="43,110,26" yaw=-30 /><!-- Middle one-->
+ <BoxCollisionShape position="-200,100,0" halfExtents="26,50,43" /><!--Three lower legs -->
+ <BoxCollisionShape position="100,100,-173" halfExtents="43,50,26" yaw=-30 />
+ <BoxCollisionShape position="100,100,-173" halfExtents="43,50,26" yaw=30 />
+ <BoxCollisionShape position="-100,264,0" halfExtents="26,105,43" roll=-49 /><!--Three upper legs -->
+ <BoxCollisionShape position="50,264,-87" halfExtents="26,105,43" roll=-49 yaw=-120 />
+ <BoxCollisionShape position="50,264,87" halfExtents="26,105,43" roll=-49 yaw=-240 />
+ </collisionShapes>
+ </Pawn>
+ </Template>
+
+ <Pawn name="statA" team=0 radarname="Outer Base - Sector 4B" position="<?lua printC(cStationA) ?>" direction="<?lua printC(cSpawn) ?>" yaw=45 pitch=-5 roll=-25 initialhealth=10000 maxhealth=10000 >
+ <templates>
+ <Template link="station" />
+ </templates>
+ <attached>
+ <DockingTarget name="dockTargetA" />
+ <Dock position="0,0,0" active=true>
+ <animations>
+ <MoveToDockingTarget target="dockTargetA" />
+ </animations>
+ <effects>
+ <DockToShip target="newSpaceShip" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="dockA" />
+ </execute>
+ </events>
+ <attached>
+ <DistanceTrigger position="0,0,0" distance="200" target="SpaceShip" beaconMode="exclude" targetname="NPC" name="dockA" />
+ <Billboard position="0,0,0" amplitude=1 material="Flares/lensflare" colour="1,0,0.05" />
+ </attached>
+ </Dock>
+ </attached>
+ </Pawn>
+
+ <!-- EnemyStation -->
+
+ <!-- Marking Billboard -->
+ <Billboard visible=false position="<?lua printC(cEnemyBaseStation1) ?>" amplitude=30 scale=2 material="Flares/lensflare" colour="0,0,1">
+ <events>
+ <visibility>
+ <EventListener event="reachedSector" />
+ </visibility>
+ </events>
+ </Billboard>
+
+
+ <Pawn name="statB" team=1 radarname="EnemyBase" position="<?lua printC(cEnemyBaseStation1) ?>" direction="<?lua printC(cSpawn) ?>" yaw=45 pitch=-5 roll=-25 initialhealth=10000 maxhealth=10000 >
+ <templates>
+ <Template link="station" />
+ </templates>
+ <events>
+ <visibility>
+ <EventListener event="reachedEnemyStation" />
+ </visibility>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ </Pawn>
+
+ <!-- New SpaceShip as destination of dock A-->
+ <SpaceShip
+ template = "spaceshipassff"
+ team = "0"
+ position = "<?lua printC(cNewShip) ?>"
+ lookat = "<?lua printC(cSector) ?>"
+ health = "1500"
+ initialhealth = "1500"
+ maxhealth = "1500"
+ shieldhealth = "80"
+ initialshieldhealth = "80"
+ maxshieldhealth = "120"
+ shieldabsorption = "0.8"
+ reloadrate = "1"
+ reloadwaittime = "1"
+ name = "newSpaceShip"
+ radarname = "ScoutShip" >
+ <attached>
+ <DockingTarget name="newSpaceShip" />
+ <DistanceTriggerBeacon name="newSpaceShip" />
+ </attached>
+ </SpaceShip>
+
+ <!--ELEMENTS -->
+
+ <?lua
+ for i = 1, 64, 1
+ do
+ rBillboard = {math.sin(i*math.pi/32)*radSector, 0, math.cos(i*math.pi/32)*radSector}
+ cBillNow = addC(cSector,rBillboard)
+ ?>
+ <Billboard position="<?lua printC(cBillNow) ?>" scale=10 material="Flares/lensflare" colour="1,0.2,0.2" visible=false>
+ <events>
+ <visibility>
+ <EventListener event="dockedA" />
+ </visibility>
+ </events>
+ </Billboard>
+ <?lua end ?>
+
+ <!-- Asteroids you have to fly through to get to the EnemyBase -->
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidField(cField1[1], cField1[2], cField1[3], 20, 30, 4500, 500, 0)
+ ?>
+
+ <!-- Other Asteroid-Fields -->
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidField(cField2[1], cField2[2], cField2[3], 20, 30, 4500, 500, 0)
+ ?>
+
+ <!-- Planets -->
+
+ <Planet
+ position="<?lua printC(cPlanet1) ?>"
+ scale="3000"
+ collisionType="dynamic"
+ linearDamping="0.8"
+ angularDamping="0"
+ mass="5000000"
+ pitch="0"
+ mesh="planets/muunilinst.mesh"
+ atmosphere="atmosphere1"
+ rotationaxis="1,0,0"
+ rotationrate="1.0"
+ atmospheresize="80.0f"
+ imagesize="1024.0f"
+ collisiondamage=2
+ enablecollisiondamage=true
+ visible=true
+ active=ture
+ >
+ <attached>
+ <ForceField position="0,0,0" mode="sphere" diameter="6000" velocity="-500" />
+ </attached>
+ <collisionShapes>
+ <SphereCollisionShape radius="3000" position="0,0,0" />
+ </collisionShapes>
+ </Planet>
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidBelt(cPlanet1[1], cPlanet1[2], cPlanet1[3], 30, 20, 100, 20, 40, 3400, 3700, 400, 1)
+ ?>
+
+ <Planet
+ position="<?lua printC(cPlanet2) ?>"
+ scale="2000"
+ collisionType="dynamic"
+ linearDamping="0.8"
+ angularDamping="0"
+ mass="5000000"
+ pitch="0"
+ mesh="planets/ganymede.mesh"
+ atmosphere="atmosphere1"
+ rotationaxis="1,0,0"
+ rotationrate="1.0"
+ atmospheresize="80.0f"
+ imagesize="1024.0f"
+ collisiondamage=2
+ enablecollisiondamage=true
+ visible=true
+ active=true
+ >
+ <attached>
+ <ForceField position="0,0,0" mode="sphere" diameter="4000" velocity="-500" />
+ </attached>
+ <collisionShapes>
+ <SphereCollisionShape radius="2000" position="0,0,0" />
+ </collisionShapes>
+ </Planet>
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidBelt(cPlanet2[1], cPlanet2[2], cPlanet2[3], 30, 20, 100, 20, 40, 3400, 3700, 400, 1)
+ ?>
+
+ <!-- EnemyPlanet(s) -->
+
+ <Planet
+ position="<?lua printC(cEnemyBasePlanet) ?>"
+ scale="5000"
+ collisionType="dynamic"
+ linearDamping="0.8"
+ angularDamping="0"
+ mass="5000000"
+ pitch="0"
+ mesh="planets/jupiter.mesh"
+ atmosphere="atmosphere1"
+ rotationaxis="1,0,0"
+ rotationrate="1.0"
+ atmospheresize="80.0f"
+ imagesize="1024.0f"
+ collisiondamage=2
+ enablecollisiondamage=true
+ visible=false
+ active=false
+ >
+ <attached>
+ <ForceField position="0,0,0" mode="sphere" diameter="10000" velocity="-500" />
+ </attached>
+ <collisionShapes>
+ <SphereCollisionShape radius="5000" position="0,0,0" />
+ </collisionShapes>
+ </Planet>
+
+ <?lua
+ xi = 5
+ zi = 5
+ for k = 1, xi, 1
+ do
+ ?>
+ <?lua
+ for j = 1, zi, 1
+ do
+ x = -2500+k*100
+ z = -4400+j*100
+ ?>
+ <SpaceShip visible=false active=false name="enemyStalled" radarname="Attacker" position="-11000,<?lua print(z)?>,<?lua print(x)?>" lookat="0,0,0" team=1>
+ <templates>
+ <Template link="spaceshippirate" />
+ </templates>
+ <events>
+ <visibility>
+ <EventListener event="reachedEnemyStation" />
+ </visibility>
+ </events>
+ </SpaceShip>
+ <?lua end ?>
+ <?lua end ?>
+
+ <SpaceShip visible=false active=false name="enemy" radarname="Guard" position="-2700,-800,-800" lookat="0,0,0" team=1>
+ <templates>
+ <Template link=spaceshippirate />
+ </templates>
+ <events>
+ <visibility>
+ <EventListener event="reachedEnemyStation" />
+ </visibility>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ <controller>
+ <WaypointPatrolController active=false accuracy=40 alertnessradius=2000 team=1>
+ <events>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ <waypoints>
+ <StaticEntity position="-3400,-1200,-200" />
+ <StaticEntity position="-1600,-1000,-200" />
+ <StaticEntity position="-1700,-1400,-940" />
+ <StaticEntity position="-2100,-1200,-1250" />
+ <StaticEntity position="-2700,-800,-800" />
+ </waypoints>
+ </WaypointPatrolController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip visible=false active=false name="enemy" radarname="Guard" position="-3400,-1200,-200" lookat="0,0,0" team=1>
+ <events>
+ <visibility>
+ <EventListener event="reachedEnemyStation" />
+ </visibility>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ <templates>
+ <Template link=spaceshippirate />
+ </templates>
+ <controller>
+ <WaypointPatrolController active=false accuracy=40 alertnessradius=2000 team=1>
+ <events>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ <waypoints>
+ <StaticEntity position="-1600,-1000,-200" />
+ <StaticEntity position="-1700,-1400,-940" />
+ <StaticEntity position="-2100,-1200,-1250" />
+ <StaticEntity position="-2700,-800,-800" />
+ <StaticEntity position="-3400,-1200,-200" />
+ </waypoints>
+ </WaypointPatrolController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip visible=false active=false name="enemy" radarname="Guard" position="-1600,-1000,-200" lookat="0,0,0" team=1>
+ <events>
+ <visibility>
+ <EventListener event="reachedEnemyStation" />
+ </visibility>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ <templates>
+ <Template link=spaceshippirate />
+ </templates>
+ <controller>
+ <WaypointPatrolController active=false accuracy=40 alertnessradius=2000 team=1>
+ <events>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ <waypoints>
+ <StaticEntity position="-1700,-1400,-940" />
+ <StaticEntity position="-2100,-1200,-1250" />
+ <StaticEntity position="-2700,-800,-800" />
+ <StaticEntity position="-3400,-1200,-200" />
+ <StaticEntity position="-1600,-1000,-200" />
+ </waypoints>
+ </WaypointPatrolController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip visible=false active=false name="enemy" radarname="Guard" position="-1700,-1400,-940" lookat="0,0,0" team=1>
+ <events>
+ <visibility>
+ <EventListener event="reachedEnemyStation" />
+ </visibility>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ <templates>
+ <Template link=spaceshippirate />
+ </templates>
+ <controller>
+ <WaypointPatrolController active=false accuracy=40 alertnessradius=2000 team=1>
+ <events>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ <waypoints>
+ <StaticEntity position="-2100,-1200,-1250" />
+ <StaticEntity position="-2700,-800,-800" />
+ <StaticEntity position="-3400,-1200,-200" />
+ <StaticEntity position="-1600,-1000,-200" />
+ <StaticEntity position="-1700,-1400,-940" />
+ </waypoints>
+ </WaypointPatrolController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip visible=false active=false name="enemy" radarname="Guard" position="-2100,-1200,-1250" lookat="0,0,0" team=1>
+ <events>
+ <visibility>
+ <EventListener event="reachedEnemyStation" />
+ </visibility>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ <templates>
+ <Template link=spaceshippirate />
+ </templates>
+ <controller>
+ <WaypointPatrolController active=false accuracy=40 alertnessradius=2000 team=1>
+ <events>
+ <activity>
+ <EventListener event="reachedEnemyStation" />
+ </activity>
+ </events>
+ <waypoints>
+ <StaticEntity position="-2700,-800,-800" />
+ <StaticEntity position="-3400,-1200,-200" />
+ <StaticEntity position="-1600,-1000,-200" />
+ <StaticEntity position="-1700,-1400,-940" />
+ <StaticEntity position="-2100,-1200,-1250" />
+ </waypoints>
+ </WaypointPatrolController>
+ </controller>
+ </SpaceShip>
+
+ </Scene>
+</Level>
Modified: code/branches/presentationHS15/data/levels/missionOne.oxw
===================================================================
--- code/branches/presentationHS15/data/levels/missionOne.oxw 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/data/levels/missionOne.oxw 2015-12-11 14:26:20 UTC (rev 10970)
@@ -1678,12 +1678,12 @@
</SimpleNotification>
<!-- @Triggers: HACK. The attacktrigger6 Event is created, but does not trigger the Script.
-(WTF?) TODO: looks like a BUG
+(WTF?) TODO: looks like a BUG
Thus a distanceTrigger is created, that gets enabled, when the inner trigger gets activated.
Due to the large radius it is likely that it actually gets triggered.
-->
- <DistanceTrigger name="testDistanceTrigger" position="0,0,0" distance=10000 target="SpaceShip" stayActive="true" delay=37.0>
+ <DistanceTrigger name="testDistanceTrigger" position="0,0,0" distance=10000 target="Pawn" stayActive="true" delay=37.0>
<EventTrigger name="testEventTrigger" activations="1" stayactive="true" delay=0.1>
<events>
<trigger>
Copied: code/branches/presentationHS15/data/levels/shuttleAttack.oxw (from rev 10967, code/branches/campaignHS15/data/levels/shuttleAttack.oxw)
===================================================================
--- code/branches/presentationHS15/data/levels/shuttleAttack.oxw (rev 0)
+++ code/branches/presentationHS15/data/levels/shuttleAttack.oxw 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,1171 @@
+<!--TODO: Shuttle and Stations -->
+<LevelInfo
+ name = "Shuttle under Attack"
+ description = "The newly discovered hostile alien species is attacking one of our outset stations, Andromeda! There is no protecting it; you have to escort the escape shuttle to a safer location."
+ tags = "mission"
+ screenshot = "shuttleProtect.png"
+/>
+
+<?lua
+ include("stats.oxo")
+ include("HUDTemplates3.oxo")
+ include("templates/lodInformation.oxt")
+
+ include("templates/spaceshipAssff.oxt")
+ include("templates/spaceshipPirate.oxt")
+ include("templates/spaceshipEscort.oxt")
+ include("templates/spaceshipShuttle.oxt")
+ include("templates/FPS.oxt")
+ include("templates/pickupRepresentationTemplates.oxt")
+?>
+
+<Level gametype = "Mission">
+ <templates>
+ <Template link="lodtemplate_default" />
+ </templates>
+
+ <?lua include("includes/notifications.oxi") ?>
+
+ <NotificationQueueCEGUI
+ name="narrative"
+ targets="simpleNotification"
+ size=3
+ displayTime=3.9
+ position="0.15, 0, 0.1, 0"
+ fontSize="15"
+ fontColor="0.3, 1, 0.2, 0.8"
+ alignment="HorzCentred"
+ displaySize="0.7, 0, 0, 0"
+ />
+
+ <!-- GLOBAL LUA VARIABLES -->
+ <?lua
+ waves = 3
+ enemiesInit = 5
+ enemiesIncrease = 2
+ allies = 3
+
+ --[[ Coordinates in (y,z,x). NOTE: Indexing starts at 1 in lua! Don“t forget to adapt the for loops, too! ]]--
+ cCenter = {0, 0, 0}
+ cSpawn = {-50, 0, 0}
+ cUnit = {-2000, 0, 3000}
+ cA = {-3000, 0, 5000}
+ cB = {-3000, 0, -5000}
+ cC = {-2300, 0, 0}
+ dStation = {1, 0, 0}
+ cNewShip = {-2100, 0, 4100}
+ cFPSGround = {-2300, 800, 0}
+ cFPS = {-2300, 1000, 0}
+ cField1 = {400, 0, 2500}
+ cField2 = {400, 0, -2500}
+ cPlanet1 = {8000, -2000, 15000}
+ cPlanet2 = {-20000, 4000, -1000}
+ rAllies = {3000, -2000} --[[ To be addressed directly, hence r. Do not permute! ]]--
+
+ --[[ Function to print Coordinates. Quotes not included! ]]--
+ function printC(coord)
+ print(coord[1] .. [[,]] .. coord[2] .. [[,]] .. coord[3])
+ end
+ ?>
+
+ <Scene
+ ambientlight = "0.8, 0.8, 0.8"
+ skybox = "Orxonox/skyBoxMoreNebula"
+ hasPhysics = true
+ >
+
+ <SpawnPoint name="playerSpawn" team=0 position="<?lua printC(cSpawn) ?>" lookat="<?lua printC(cA) ?>" spawnclass=SpaceShip pawndesign=spaceshipescort />
+
+ <WorldAmbientSound source="Earth.ogg" looping="true" playOnLoad="true" />
+
+ <Light type=directional position="<?lua printC(cCenter) ?>" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0"/>
+
+ <!--QUEST DEFINITIONS-->
+
+ <GlobalQuest id="quest1">
+ <QuestDescription title="Reach Andromeda Station!" description="You need to get in contact with your base! Word is enemies are preparing to attack our people and goods! Be quick!" failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <complete-effects>
+ <AddQuest questId="quest2" />
+ <AddQuest questId="quest2.1" />
+ </complete-effects>
+ </GlobalQuest>
+
+ <GlobalQuest id="quest2">
+ <QuestDescription title="Prepare to fight the Enemy" description="You need to be prepared, mentally and physically! So gather all your strength and forces to destroy those space pirates!" failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <subquests>
+ <GlobalQuest id="quest2.1">
+ <QuestDescription title="> Get a better Spaceship" description="Take over the faster, stronger, more secure and overall better spaceship!" failMessage="" completeMessage="" />
+ <complete-effects>
+ <AddQuest questId="quest2.2" />
+ </complete-effects>
+ </GlobalQuest>
+ <GlobalQuest id="quest2.2">
+ <QuestDescription title="> Meet your Unit" description="Your unit will help you, where ever you go. To victory or to death, they will be loyal to you!" failMessage="" completeMessage="" />
+ </GlobalQuest>
+ </subquests>
+ <complete-effects>
+ <AddQuest questId="quest3" />
+ </complete-effects>
+ </GlobalQuest>
+
+ <GlobalQuest id="quest3">
+ <QuestDescription title="Fight the first Wave" description="Five enemies are approaching you! There main target is the shuttle though, so destroy them - before the destroy the escape shuttle with the valuebals goods (and of course the people aboard)!" failMessage="Oh no! You have to be better, they destroyed the shuttle!" completeMessage="Good Job!" />
+ <hints>
+ </hints>
+ <complete-effects>
+ <AddQuest questId="quest4" />
+ <AddQuest questId="quest4.1" />
+ <AddQuest questId="quest4.2" />
+ </complete-effects>
+ </GlobalQuest>
+
+ <GlobalQuest id="quest4">
+ <QuestDescription title="Prepare for the next Wave" description="This was just a scouting troop from the enemies, they know now how many there are from us and will send a bigger troop next time! Prepare yourself..." failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <subquests>
+ <GlobalQuest id="quest4.1">
+ <QuestDescription title="> Get to the Defense Station" description="Fly to the defense station, we will guard your spaceship while you will fight them with the Cannon Suit." failMessage="" completeMessage="" />
+ </GlobalQuest>
+ <GlobalQuest id="quest4.2">
+ <QuestDescription title="> Get into the Cannon Suit!" description="Dock to the defense station, you will be able to contol the Cannon Suit on top of the station, perfect for fighting off a hord of enemies!" failMessage="" completeMessage="" />
+ </GlobalQuest>
+ </subquests>
+ <complete-effects>
+ <AddQuest questId="quest5" />
+ </complete-effects>
+ </GlobalQuest>
+
+ <GlobalQuest id="quest5">
+ <QuestDescription title="Fight the Hord!" description="Destroy the next wave!" failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <complete-effects>
+ <AddQuest questId="quest6" />
+ <AddQuest questId="quest6.1" />
+ <AddQuest questId="quest6.2" />
+ </complete-effects>
+ </GlobalQuest>
+
+ <GlobalQuest id="quest6">
+ <QuestDescription title="Get back for the Showdown" description="Undock from the defense station and get into your Spaceship!" failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <subquests>
+ <GlobalQuest id="quest6.1">
+ <QuestDescription title="> Collect the local Pickups" description="There is a box with pickups close to the station, you can collect them if you want to, but it is advised to do so. They will support your task in destroying the enemies and make your life easier." failMessage="" completeMessage="" />
+ </GlobalQuest>
+ <GlobalQuest id="quest6.2">
+ <QuestDescription title="> Get back to the Shuttle" description="Fly to the Shuttle!" failMessage="" completeMessage="" />
+ </GlobalQuest>
+ </subquests>
+ <complete-effects>
+ <AddQuest questId="quest7" />
+ </complete-effects>
+ </GlobalQuest>
+
+ <GlobalQuest id="quest7">
+ <QuestDescription title="Fight the final Wave" description="Good gracious, another hord of pirate ships!" failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <subquests>
+ </subquests>
+ </GlobalQuest>
+
+ <!--EVENTS AND TRIGGERS
+ Usable events and triggers:
+ _spawntrigger
+ _reachedA
+ _dock<A|B|C>
+ _docked<A> WIP; see below
+ -joinedUnit
+ _wave<k>
+ _killedEnemy<k>.<i>
+ _waveClear<k>
+ -->
+
+
+
+ <EventMultiTrigger name="spawntrigger" activations=1>
+ <events>
+ <trigger>
+ <EventListener event="playerSpawn" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <DistanceTrigger name="reachedA" position="<?lua printC(cA) ?>" distance=1000 target="SpaceShip" beaconMode="exclude" targetname="NPC" stayactive=true />
+
+ <!-- HACK: just waited out 3sec for animation. Cannot link an event to the COMPLETION of a dock. How is this not possible?? -->
+ <EventMultiTrigger name="dockedA" activations="1" stayactive="true" delay=3>
+ <events>
+ <trigger>
+ <EventListener event="dockA" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <DistanceTrigger name="joinedUnit" active=false position="<?lua printC(cUnit) ?>" distance=100 target="SpaceShip" beaconMode="exclude" targetname="NPC" stayactive=true>
+ <events>
+ <activity>
+ <EventListener event="dockedA" />
+ </activity>
+ </events>
+ </DistanceTrigger>
+
+ <EventMultiTrigger name="wave1" activations="1" delay=4>
+ <events>
+ <trigger>
+ <EventListener event="joinedUnit" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <!-- Recursive helper function for the end-of-wave events. F*ck the event system, seriously. -->
+ <?lua
+ function enemyTriggerRecursor(i, k)
+ if i > 0 then
+ return [[
+ <EventTrigger name=killedEnemy]] .. k .. [[.]] .. i .. [[ activations=1 stayactive=true delay=0.1>
+ <events>
+ <trigger>
+ <EventListener event=attackers]] .. k .. [[ />
+ </trigger>
+ </events>
+ ]] .. enemyTriggerRecursor(i-1, k) .. [[
+ </EventTrigger>
+ ]]
+ else return ""
+ end
+ end
+ ?>
+ <!-- Actual recursive Event(s) for the respective waves. -->
+ <?lua
+ enemies = enemiesInit
+ for k = 1, waves, 1
+ do
+ print(enemyTriggerRecursor(enemies,k))
+ ?>
+ <EventMultiTrigger name="waveClear<?lua print(k) ?>" delay=4.0>
+ <events>
+ <trigger>
+ <EventListener event="killedEnemy<?lua print(k .. [[.]] .. enemies) ?>" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+ <?lua enemies = enemies + enemiesIncrease ?>
+ <?lua end ?>
+
+ <!-- This controls the ally AI controller so it is only active when active enemies are around! -->
+ <EventDispatcher name="allyControllerDispatcher">
+ <targets>
+ <EventTarget target="allyController" />
+ </targets>
+ <events>
+ <activity>
+ <?lua
+ for k = 1, waves, 1 do
+ ?>
+ <Trigger mode=and>
+ <EventTrigger>
+ <events>
+ <trigger>
+ <EventListener event="wave<?lua print(k) ?>" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <EventTrigger invert=true>
+ <events>
+ <trigger>
+ <EventListener event="waveClear<?lua print(k) ?>" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </Trigger>
+ <?lua end ?>
+ </activity>
+ </events>
+ </EventDispatcher>
+
+ <DistanceTrigger active=false name="reachedC" position="<?lua printC(cC) ?>" distance=400 target="SpaceShip" beaconMode="exclude" targetname="NPC" stayactive=true>
+ <events>
+ <activity>
+ <EventListener event="waveClear1" />
+ </activity>
+ </events>
+ </DistanceTrigger>
+
+ <EventMultiTrigger name="dockedC" activations="1" stayactive="true" delay=3>
+ <events>
+ <trigger>
+ <EventListener event="dockC" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <EventMultiTrigger name="wave2" activations="1" delay=8>
+ <events>
+ <trigger>
+ <EventListener event="dockedC" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <EventMultiTrigger name="readyAfterWave2" activations="1" delay=2 stayactive=true>
+ <events>
+ <trigger>
+ <Trigger mode=and>
+ <EventTrigger>
+ <events>
+ <trigger>
+ <EventListener event="undockC" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <EventTrigger>
+ <events>
+ <trigger>
+ <EventListener event="waveClear2" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </Trigger>
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <!-- See the DistanceTrigger attached to the shuttle here! !-->
+
+ <EventMultiTrigger name="wave3" activations="1" delay=12>
+ <events>
+ <trigger>
+ <EventListener event="reachedShuttle" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <DistanceTrigger active=false name="reachedB" position="<?lua printC(cB) ?>" distance=400 target="SpaceShip" beaconMode="exclude" targetname="NPC" stayactive=true>
+ <events>
+ <activity>
+ <EventListener event="waveClear3" />
+ </activity>
+ </events>
+ </DistanceTrigger>
+
+ <Script code="Mission endMission true" onLoad="false">
+ <events>
+ <trigger>
+ <EventListener event="reachedB" />
+ </trigger>
+ </events>
+ </Script>
+
+ <EventMultiTrigger name="missionFailed" activations="1" stayactive=true>
+ <events>
+ <trigger>
+ <EventListener event="transporter" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <EventMultiTrigger name="failMissionHelper" delay=4 stayactive=true>
+ <events>
+ <trigger>
+ <EventListener event="missionFailed" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <DistanceTrigger active=false name="failMission" position="<?lua printC(cA) ?>" distance=100 target="SpaceShip" beaconMode="exclude" targetname="NPC" stayactive=true>
+ <events>
+ <activity>
+ <EventListener event="failMissionHelper" />
+ </activity>
+ </events>
+ </DistanceTrigger>
+
+ <!--HACK: Ultimately settled on docking A to fail the mission... that makes a whole lot of sense. -->
+
+ <Script code="Mission endMission fail" onLoad="false">
+ <events>
+ <trigger>
+ <EventListener event="failMission" />
+ </trigger>
+ </events>
+ </Script>
+
+ <!--QUEST EFFECT BEACONS -->
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <AddQuest questId="quest1" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="spawntrigger" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest1" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="reachedA" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest2.1" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="dockedA" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest2.2" />
+ <CompleteQuest questId="quest2" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="joinedUnit" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest3" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="waveClear1" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest4.1" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="reachedC" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest4.2" />
+ <CompleteQuest questId="quest4" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="dockedC" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest5" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="waveClear2" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest6.1" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="gotPickups" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest6.2" />
+ <CompleteQuest questId="quest6" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="reachedShuttle" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest7" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="waveClear3" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <!--NOTIFICATIONS -->
+
+ <SimpleNotification broadcast="true" message="Welcome, Commander. Please report at Andromeda Station.">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=4 >
+ <events>
+ <trigger>
+ <EventListener event="spawntrigger" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Our enemy is set to attack us very soon.">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=8 >
+ <events>
+ <trigger>
+ <EventListener event="spawntrigger" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Please study your mission briefing!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=12 >
+ <events>
+ <trigger>
+ <EventListener event="spawntrigger" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Welcome to Andromeda, Commander.">
+ <events>
+ <trigger>
+ <EventListener event="reachedA" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="We've prepared a reinforced Ship for you.">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=4 >
+ <events>
+ <trigger>
+ <EventListener event="reachedA" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Now join our defense Team.">
+ <events>
+ <trigger>
+ <EventListener event="dockedA" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Howdy Commander! Ready to kick some alien ass?">
+ <events>
+ <trigger>
+ <EventListener event="joinedUnit" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <!-- HACK: Somehow only fires a second time if the (notification,event) pairs are separate! WTF -->
+ <?lua
+ for k = 1, waves, 1 do
+ ?>
+ <SimpleNotification broadcast="true" message="An enemy wave is approaching the shuttle!">
+ <events>
+ <trigger>
+ <EventListener event="wave<?lua print(k) ?>" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+ <?lua end ?>
+
+ <SimpleNotification broadcast="true" message="yippie ki yay motherf*cker!">
+ <events>
+ <trigger>
+ <EventListener event="attackers1" />
+ <EventListener event="attackers2" />
+ <EventListener event="attackers3" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Phew, that was close! Well done, Commmander.">
+ <events>
+ <trigger>
+ <EventListener event="waveClear1" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="But it's not over yet! Get to the defense station and dock!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=4 >
+ <events>
+ <trigger>
+ <EventListener event="waveClear1" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="This is our powerful reinforced cannon suit.">
+ <events>
+ <trigger>
+ <EventListener event="dockedC" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="It should deal with those pesky invaders!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=4 >
+ <events>
+ <trigger>
+ <EventListener event="dockedC" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Brilliant work, Commander! now undock again.">
+ <events>
+ <trigger>
+ <EventListener event="waveClear2" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Here's some supplies for you. Shoot that crate!">
+ <events>
+ <trigger>
+ <EventListener event="readyAfterWave2" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Our Intelligence reports one more wave...">
+ <events>
+ <trigger>
+ <EventListener event="reachedShuttle" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Ready to be a hero, Commander?">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=4 >
+ <events>
+ <trigger>
+ <EventListener event="reachedShuttle" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Congrats, Commander! You saved our skin.">
+ <events>
+ <trigger>
+ <EventListener event="waveClear3" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Get over to the safe base to take a break.">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=4 >
+ <events>
+ <trigger>
+ <EventListener event="waveClear3" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="It's over... we failed. Retreat to Andromeda!">
+ <events>
+ <trigger>
+ <EventListener event="missionFailed" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <!--STATIONS -->
+
+ <!-- (Temporary) Template for stations. Used to define common features of all Stations. -->
+ <Template name="station">
+ <Pawn mass=10000000 collisionType=dynamic friction=0.01>
+ <attached>
+ <Model mesh="HydroHarvester.mesh" position="0,0,0" scale=50 />
+ <DistanceTriggerBeacon name="NPC" />
+ </attached>
+ <collisionShapes>
+ <BoxCollisionShape position="-560,0,0" halfExtents="115,100,245" /><!-- Three lower boxes -->
+ <BoxCollisionShape position="290,0,-480" halfExtents="115,100,245" yaw=-120 />
+ <BoxCollisionShape position="290,0,480" halfExtents="115,100,245" yaw=-240 />
+ <BoxCollisionShape position="-280,0,0" halfExtents="163,50,50" /><!-- Three lower connections -->
+ <BoxCollisionShape position="140,0,-240" halfExtents="163,50,50" yaw=-120 />
+ <BoxCollisionShape position="140,0,240" halfExtents="163,50,50" yaw=-240 />
+ <BoxCollisionShape position="0,530,0" halfExtents="172,52,298" /><!-- Upper Tower -->
+ <BoxCollisionShape position="0,530,0" halfExtents="172,52,298" yaw=-120 />
+ <BoxCollisionShape position="0,530,0" halfExtents="172,52,298" yaw=-240 />
+ <BoxCollisionShape position="0,400,0" halfExtents="43,110,26" yaw=-30 /><!-- Middle one-->
+ <BoxCollisionShape position="-200,100,0" halfExtents="26,50,43" /><!--Three lower legs -->
+ <BoxCollisionShape position="100,100,-173" halfExtents="43,50,26" yaw=-30 />
+ <BoxCollisionShape position="100,100,-173" halfExtents="43,50,26" yaw=30 />
+ <BoxCollisionShape position="-100,264,0" halfExtents="26,105,43" roll=-49 /><!--Three upper legs -->
+ <BoxCollisionShape position="50,264,-87" halfExtents="26,105,43" roll=-49 yaw=-120 />
+ <BoxCollisionShape position="50,264,87" halfExtents="26,105,43" roll=-49 yaw=-240 />
+ </collisionShapes>
+ </Pawn>
+ </Template>
+
+ <!-- A, Coordinates are approx. (cos(29pi/16), sin(29pi/16), 0)*3000 -->
+ <Pawn name="statA" team=0 radarname="Andromeda Station" position="<?lua printC(cA) ?>" direction="<?lua printC(dStation) ?>" yaw=-50 initialhealth=10000 maxhealth=10000>
+ <templates>
+ <Template link="station" />
+ </templates>
+ <attached>
+ <DockingTarget name="dockTargetA" />
+ <Dock position="0,0,0" active=true>
+ <animations>
+ <MoveToDockingTarget target="dockTargetA" />
+ </animations>
+ <effects>
+ <DockToShip target="newSpaceShip" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="dockA" />
+ </execute>
+ </events>
+ <attached>
+ <DistanceTrigger position="0,0,0" distance="200" target="SpaceShip" beaconMode="exclude" targetname="NPC" name="dockA" />
+ <Billboard position="0,0,0" amplitude=1 material="Flares/lensflare" colour="1,0,0.05" />
+ </attached>
+ </Dock>
+ </attached>
+ </Pawn>
+
+ <!-- B, Coordinates are approx. (-cos(29pi/16), sin(29pi/16), 0)*3000 -->
+ <Pawn name="statB" team=0 radarname="Safe Base" position="<?lua printC(cB) ?>" direction="<?lua printC(dStation) ?>" yaw=210 initialhealth=10000 maxhealth=10000>
+ <templates>
+ <Template link="station" />
+ </templates>
+ <attached>
+ <DockingTarget name="dockTargetB" />
+ <Dock position="0,0,0" active=false>
+ <animations>
+ <MoveToDockingTarget target="dockTargetB" />
+ </animations>
+ <effects>
+ <DockToShip target="newSpaceShip" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="dockB" />
+ </execute>
+ </events>
+ <attached>
+ <DistanceTrigger position="0,0,0" distance="200" target="SpaceShip" beaconMode="exclude" targetname="NPC" name="dockB" />
+ <Billboard position="0,0,0" amplitude=1 material="Flares/lensflare" colour="1,0,0.05" />
+ </attached>
+ </Dock>
+ </attached>
+ </Pawn>
+
+ <!-- C -->
+ <Pawn name="statC" team=0 radarname="Defense Station" position="<?lua printC(cC) ?>" direction="<?lua printC(dStation) ?>" initialhealth=10000 maxhealth=10000>
+ <templates>
+ <Template link="station" />
+ </templates>
+ <attached>
+ <DockingTarget name="dockTargetC" />
+ <Dock position="0,0,0">
+ <animations>
+ <MoveToDockingTarget target="dockTargetC" />
+ </animations>
+ <effects>
+ <DockToShip target="fpsMode" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="dockC" />
+ </execute>
+ </events>
+ <attached>
+ <!--HACK: We use another dock to undock back to the ship since undocking is not implemented... -->
+ <Dock position="0,0,0" active=true>
+ <effects>
+ <DockToShip target="newSpaceShip" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="undockC" />
+ </execute>
+ </events>
+ </Dock>
+ <DistanceTrigger active=false position="0,0,0" distance="200" target="SpaceShip" beaconMode="exclude" targetname="NPC" name="dockC">
+ <events>
+ <activity>
+ <EventListener event="reachedC" />
+ </activity>
+ </events>
+ </DistanceTrigger>
+ <Billboard position="0,0,0" amplitude=1 material="Flares/lensflare" colour="1,0,0.05" />
+ </attached>
+ </Dock>
+ </attached>
+ </Pawn>
+
+ <!-- New SpaceShip as destination of dock A-->
+ <SpaceShip
+ template = "spaceshipassff"
+ team = "0"
+ position = "<?lua printC(cNewShip) ?>"
+ lookat = "<?lua print(rAllies[2] .. ',' .. [[0]] .. ',' .. rAllies[1]) ?>"
+ health = "400"
+ initialhealth = "400"
+ maxhealth = "1500"
+ shieldhealth = "80"
+ initialshieldhealth = "80"
+ maxshieldhealth = "120"
+ shieldabsorption = "0.8"
+ reloadrate = "1"
+ reloadwaittime = "1"
+ name = "newSpaceShip"
+ radarname = "Defender" >
+ <attached>
+ <DockingTarget name="newSpaceShip" />
+ <DistanceTriggerBeacon name="newSpaceShip" />
+ </attached>
+ </SpaceShip>
+
+ <!-- FPS Player as destination of dock C -->
+ <FpsPlayer team=0 template = "fps" radarname = "Cannon Suit" position = "<?lua printC(cFPS) ?>" lookat="<?lua printC(cCenter) ?>">
+ <attached>
+ <DockingTarget name="fpsMode" />
+ <DistanceTriggerBeacon name="fpsPlayer" />
+ </attached>
+ <collisionShapes>
+ <BoxCollisionShape position="0,0,0" halfExtents="1,1,1"/>
+ </collisionShapes>
+ </FpsPlayer>
+
+ <!-- Floor for FPS Player -->
+ <StaticEntity position="<?lua printC(cFPSGround) ?>" collisionType=static mass=100000 friction=0.01 >
+ <attached>
+ <Model position="0,0,0" mesh="crate.mesh" scale3D="80,5,80" />
+ <Billboard position="320,50,320" material="Flares/ringflare2" colour="0.2,0.4,0.8" />
+ <DistanceTrigger position="320,50,320" distance="50" target="Pawn" beaconMode="identify" targetname="fpsPlayer" name="undockC" stayactive=true />
+ <ForceField active=false position="0,0,0" mode="homogen" diameter="600" forcedirection = "0,-500,0" />
+ </attached>
+ <collisionShapes>
+ <BoxCollisionShape position="0,0,0" halfExtents="400,25,400" />
+ </collisionShapes>
+ </StaticEntity>
+
+ <!--ELEMENTS -->
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidField(cField1[1], cField1[2], cField1[3], 20, 30, 2000, 250, 0)
+ ?>
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidField(cField2[1], cField2[2], cField2[3], 20, 30, 2000, 250, 0)
+ ?>
+
+ <Planet
+ position="<?lua printC(cPlanet1) ?>"
+ scale="2000"
+ collisionType="dynamic"
+ linearDamping="0.8"
+ angularDamping="0"
+ mass="5000000"
+ pitch="0"
+ mesh="planets/muunilinst.mesh"
+ atmosphere="atmosphere1"
+ rotationaxis="1,0,0"
+ rotationrate="1.0"
+ atmospheresize="80.0f"
+ imagesize="1024.0f"
+ collisiondamage = 2
+ enablecollisiondamage = true
+ >
+ <attached>
+ <ForceField position="0,0,0" mode="sphere" diameter="4000" velocity="-500" />
+ </attached>
+ <collisionShapes>
+ <SphereCollisionShape radius="2000" position="0,0,0" />
+ </collisionShapes>
+ </Planet>
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidBelt(cPlanet1[1], cPlanet1[2], cPlanet1[3], 30, 0, 30, 20, 40, 2800, 3000, 200, 1)
+ ?>
+
+ <Planet
+ position="<?lua printC(cPlanet2) ?>"
+ scale="3000"
+ collisionType="dynamic"
+ linearDamping="0.8"
+ angularDamping="0"
+ mass="5000000"
+ pitch="0"
+ mesh="planets/planet3.mesh"
+ atmosphere="atmosphere1"
+ rotationaxis="1,0,0"
+ rotationrate="1.0"
+ atmospheresize="80.0f"
+ imagesize="1024.0f"
+ collisiondamage = 2
+ enablecollisiondamage = true
+ >
+ <attached>
+ <ForceField position="0,0,0" mode="sphere" diameter="6000" velocity="-500" />
+ </attached>
+ <collisionShapes>
+ <SphereCollisionShape radius="3000" position="0,0,0" />
+ </collisionShapes>
+ </Planet>
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidBelt(cPlanet2[1], cPlanet2[2], cPlanet2[3], 30, 20, 100, 20, 40, 3400, 3700, 400, 1)
+ ?>
+
+ <Pawn team=0 health=30 position="<?lua print((cC[1]+600) .. ',' .. cC[2] .. ',' .. (cC[3]-600)) ?>" direction="0,-1,0" collisionType=dynamic mass=1000 radarname="Supplies" name="gotPickups">
+ <events>
+ <visibility>
+ <EventListener event="readyAfterWave2" />
+ </visibility>
+ <activity>
+ <EventListener event="readyAfterWave2" />
+ </activity>
+ </events>
+ <attached>
+ <Model position="0,0,0" mesh="crate.mesh" scale3D="10,10,10" />
+ </attached>
+ <collisionShapes>
+ <BoxCollisionShape position="0,0,0" halfExtents="30,30,30" />
+ </collisionShapes>
+ </Pawn>
+
+ <?lua
+ include("includes/pickups.oxi")
+ ?>
+
+ <PickupSpawner pickup=hugeshieldpickup position="<?lua print((cC[1]+585) .. ',' .. cC[2] .. ',' .. (cC[3]-585)) ?>" triggerDistance="15" maxSpawnedItems="1">
+ <events>
+ <visibility>
+ <EventListener event="readyAfterWave2" />
+ </visibility>
+ <activity>
+ <EventListener event="readyAfterWave2" />
+ </activity>
+ </events>
+ </PickupSpawner>
+
+ <PickupSpawner pickup=crazyhealthpickup position="<?lua print((cC[1]+615) .. ',' .. cC[2] .. ',' .. (cC[3]-615)) ?>" triggerDistance="15" maxSpawnedItems="1">
+ <events>
+ <visibility>
+ <EventListener event="readyAfterWave2" />
+ </visibility>
+ <activity>
+ <EventListener event="readyAfterWave2" />
+ </activity>
+ </events>
+ </PickupSpawner>
+
+ <PickupSpawner pickup=hugespeedpickup position="<?lua print((cC[1]+585) .. ',' .. cC[2] .. ',' .. (cC[3]-615)) ?>" triggerDistance="15" maxSpawnedItems="1" >
+ <events>
+ <visibility>
+ <EventListener event="readyAfterWave2" />
+ </visibility>
+ <activity>
+ <EventListener event="readyAfterWave2" />
+ </activity>
+ </events>
+ </PickupSpawner>
+
+ <!-- Allies -->
+ <?lua
+ for i = 1, allies, 1
+ do
+ x = rAllies[1] + math.cos(2*math.pi/allies*(i+1))*100
+ y = rAllies[2] + math.sin(2*math.pi/allies*(i+1))*100
+ ?>
+ <SpaceShip visible=false active=false name="allies<?lua print(k)?>" radarname="Ally" position="<?lua print(y)?>,<?lua print(math.pow(-1,i)*100) ?>,<?lua print(x)?>" lookat="0,0,0" team=0>
+ <templates>
+ <Template link="spaceshipassff" />
+ </templates>
+ <events>
+ <visibility>
+ <EventListener event="dockedA" />
+ </visibility>
+ <activity>
+ <EventListener event="dockedA" />
+ </activity>
+ </events>
+ <attached>
+ <DistanceTriggerBeacon name="NPC" />
+ </attached>
+ <controller>
+ <!-- also see allyControllerDispatcher -->
+ <AIController name="allyController" accuracy=100 team=0 active=false />
+ </controller>
+ </SpaceShip>
+ <?lua end ?>
+
+ <!-- Enemies. Outer loop defines waves, inner loop defines enemies in every wave. -->
+ <?lua
+ enemies = enemiesInit
+ for k = 1, waves, 1
+ do
+ ?>
+ <?lua
+ for i = 1, enemies, 1
+ do
+ x = math.cos(math.pi/(2*enemies - 2)*(i+k))*1500
+ y = math.sin(math.pi/(2*enemies - 2)*(i+k))*1500
+ ?>
+ <SpaceShip visible=false active=false name="attackers<?lua print(k)?>" radarname="Attacker" position="<?lua print(y)?>,<?lua print(math.pow(-1,i)*250) ?>,<?lua print(x)?>" lookat="0,0,0" team=1>
+ <templates>
+ <Template link="spaceshippirate" />
+ </templates>
+ <events>
+ <visibility>
+ <EventListener event="wave<?lua print(k)?>" />
+ </visibility>
+ <activity>
+ <EventListener event="wave<?lua print(k)?>" />
+ </activity>
+ </events>
+ <attached>
+ <DistanceTriggerBeacon name="NPC" />
+ </attached>
+ <controller>
+ <WaypointPatrolController name="attackController" accuracy=100 alertnessradius=100 team=1 active=false>
+ <waypoints>
+ <Attacher target="transporter" deletewithparent=false />
+ </waypoints>
+ <events>
+ <activity>
+ <EventListener event="wave<?lua print(k)?>" />
+ </activity>
+ </events>
+ </WaypointPatrolController>
+ </controller>
+ </SpaceShip>
+ <?lua end ?>
+ <?lua
+ enemies = enemies + enemiesIncrease
+ end ?>
+
+ <!-- Transporter, starting Point is near A, end Point near B, the circle parameters for the waypoints are: Center = (0, -887, 0), r = 2613 -->
+ <SpaceShip position="<?lua printC(cA) ?>" lookat="<?lua printC(cB) ?>" team=0 name="transporter" radarname="Shuttle" >
+ <templates>
+ <Template link="spaceshipShuttle" />
+ </templates>
+ <attached>
+ <DistanceTriggerBeacon name="NPC" />
+ <DistanceTriggerBeacon name="transporter" />
+ <DistanceTrigger active=false name="reachedShuttle" position="0,0,0" distance=400 target="SpaceShip" beaconMode="exclude" targetname="NPC" stayactive=true initialhealth=1000 maxhealth=1000>
+ <events>
+ <activity>
+ <EventListener event="readyAfterWave2" />
+ </activity>
+ </events>
+ </DistanceTrigger>
+ </attached>
+ <controller>
+ <WaypointController accuracy=10 team=0>
+ <waypoints>
+ <!-- A to B -->
+ <?lua
+ max = 5
+ for i = 1, max, 1
+ do
+ x = math.cos(math.pi*(i+1)/8)*5000
+ y = -math.sin(math.pi*(i+1)/8)*700-3000
+ ?>
+ <Billboard position="<?lua print(y) ?>,0,<?lua print(x) ?>" amplitude=1 material="Flares/lensflare" colour="1,1,0.05"/>
+ <?lua end ?>
+
+ <!-- Return Point -->
+ <Billboard position="<?lua printC(cB) ?>" amplitude=1 material="Flares/lensflare" colour="1,1,0.05"/>
+
+ <!-- B to A -->
+ <?lua
+ max = 5
+ for i = 1, max, 1
+ do
+ x = math.cos(math.pi*(max+2-i)/8)*5000
+ y = -math.sin(math.pi*(max+2-i)/8)*700-3000
+ ?>
+ <Billboard position="<?lua print(y) ?>,0,<?lua print(x) ?>" amplitude=1 material="Flares/lensflare" colour="1,1,0.05"/>
+ <?lua end ?>
+
+ <!-- Start Point -->
+ <Billboard position="<?lua printC(cA) ?>" amplitude=1 material="Flares/lensflare" colour="1,1,0.05"/>
+ </waypoints>
+ </WaypointController>
+ </controller>
+ </SpaceShip>
+
+ </Scene>
+</Level>
Copied: code/branches/presentationHS15/data/levels/shuttleRetaliation.oxw (from rev 10967, code/branches/campaignHS15/data/levels/shuttleRetaliation.oxw)
===================================================================
--- code/branches/presentationHS15/data/levels/shuttleRetaliation.oxw (rev 0)
+++ code/branches/presentationHS15/data/levels/shuttleRetaliation.oxw 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,1181 @@
+<LevelInfo
+ name = "Retaliation"
+ description = "This attack cannot be met with no consequences! Commander, we order you to get back to sector 5C and erradicate the alien menace at once!"
+ tags = "mission"
+ screenshot = "retailiation.png"
+/>
+
+<?lua
+ include("stats.oxo")
+ include("HUDTemplates3.oxo")
+ include("templates/lodInformation.oxt")
+
+ include("templates/spaceshipAssff.oxt")
+ include("templates/spaceshipPirate.oxt")
+ include("templates/spaceshipEscort.oxt")
+ include("templates/spaceshipShuttle.oxt")
+ include("templates/FPS.oxt")
+ include("templates/pickupRepresentationTemplates.oxt")
+?>
+
+<Level gametype = "Mission">
+ <templates>
+ <Template link="lodtemplate_default" />
+ </templates>
+
+ <?lua include("includes/notifications.oxi") ?>
+
+ <NotificationQueueCEGUI
+ name="narrative"
+ targets="simpleNotification"
+ size=3
+ displayTime=3.9
+ position="0.15, 0, 0.1, 0"
+ fontSize="15"
+ fontColor="0.3, 1, 0.2, 0.8"
+ alignment="HorzCentred"
+ displaySize="0.7, 0, 0, 0"
+ />
+
+ <!-- GLOBAL LUA VARIABLES -->
+ <?lua
+
+ enemies = 2
+ allies = 2
+
+ radSector = 12000
+
+ --[[ Coordinates in (y,z,x). NOTE: Indexing starts at 1 in lua! Don“t forget to adapt the for loops, too! ]]--
+ cCenter = {0, 0, 0}
+ cSpawn = {1500, -2000, 900}
+ cSector = {-15000, -5500, -9000}
+ cSectorEntry = {-4710, -5500, -2826}
+ cPathToEntry = {{0, -2000, 0}}
+ cBeacon = {-6500, -5500, -4400}
+ cAllyWait = cBeacon
+
+ cAlly = cSpawn
+ cEnemy = {-9600, -5500, -6000}
+
+ rSection= {0, -200, 0}
+ rWingman1 = {0, -100, 100}
+ rWingman2 = {0, -100, -100}
+
+ cPlanet1 = {20000, 0, 29000}
+ cPlanet2 = {-22000, 0, -29000}
+
+ cEnemyBasePlanet = {-20000, -8000, -10000}
+
+ cField1 = {-5000, -4000, -3000}
+ cField2 = {4000, 2000, 4500}
+
+
+ --[[ Function to print Coordinates. Quotes not included! ]]--
+ function printC(coord)
+ print(coord[1] .. [[,]] .. coord[2] .. [[,]] .. coord[3])
+ end
+
+ --[[ Function to add Coordinates.]]--
+ function addC(coord1, coord2)
+ return {coord1[1]+coord2[1], coord1[2]+coord2[2], coord1[3]+coord2[3]}
+ end
+ ?>
+
+ <Scene
+ ambientlight = "0.8, 0.8, 0.8"
+ skybox = "Orxonox/skyBoxMoreNebula"
+ hasPhysics = true
+ >
+
+ <WorldAmbientSound source="Earth.ogg" looping="true" playOnLoad="true" />
+
+ <Light type=directional position="<?lua printC(cSpawn) ?>" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0"/>
+
+ <!--SPAWNING-->
+
+ <Template name=commander>
+ <SpaceShip
+ template = "spaceshipassff"
+ team = "0"
+ health = "800"
+ initialhealth = "800"
+ maxhealth = "1500"
+ shieldhealth = "80"
+ initialshieldhealth = "80"
+ maxshieldhealth = "120"
+ shieldabsorption = "0.8"
+ reloadrate = "1"
+ reloadwaittime = "1"
+ name = "commander"
+ radarname = "Commander"
+ >
+ <attached>
+ <DistanceTriggerBeacon name="Commander" />
+ </attached>
+ </SpaceShip>
+ </Template>
+
+ <Template name=ally>
+ <SpaceShip
+ template = "spaceshipassff"
+ team = "0"
+ radarname = "Ally"
+ lookat = "<?lua printC(cPathToEntry[1]) ?>"
+ >
+ <attached>
+ <DistanceTriggerBeacon name="Ally" />
+ </attached>
+ </SpaceShip>
+ </Template>
+
+ <Template name=enemy>
+ <SpaceShip
+ template = "spaceshippirate"
+ team = "1"
+ radarname = "Invader"
+ lookat = "<?lua printC(cBeacon) ?>"
+ active = false
+ visible = false
+ >
+ <attached>
+ <DistanceTriggerBeacon name="Enemy" />
+ </attached>
+ </SpaceShip>
+ </Template>
+
+ <TeamSpawnPoint active=false name="playerSpawn" team=0 position="<?lua printC(cSpawn) ?>" lookat="<?lua printC(cPathToEntry[1]) ?>" spawnclass=SpaceShip pawndesign=commander>
+ <events>
+ <activity>
+ <EventTrigger invert=true>
+ <events>
+ <trigger>
+ <EventListener event="reachedSector" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </activity>
+ </events>
+ </TeamSpawnPoint>
+
+ <TeamSpawnPoint active=false name="altSpawn" team=0 position="<?lua printC(cBeacon) ?>" lookat="<?lua printC(cSector) ?>" spawnclass=SpaceShip pawndesign=commander>
+ <events>
+ <activity>
+ <EventListener event="reachedSector" />
+ </activity>
+ </events>
+ </TeamSpawnPoint>
+
+ <!--QUEST DEFINITIONS-->
+
+ <GlobalQuest id="quest1">
+ <QuestDescription title="Enter Sector 5C" description="It is time to retaliate against the aggressors. Get back to Sector 5C to kill every last one of them! We have you covered with <?lua print(allies) ?> of our finest Divisions. They will guide, help and protect you if necessary." failMessage="" completeMessage="" />
+ <hints>
+ <QuestHint id="quest1hint1">
+ <QuestDescription title="Markings" description="We have marked the bounds of Sector 5C in red lights, you can follow the green trail to get there." />
+ </QuestHint>
+ </hints>
+ </GlobalQuest>
+
+ <GlobalQuest id="quest2">
+ <QuestDescription title="Find them" description="It seems they have hidden themselves, that is, their whole civilization, in fear of retaliation. Our scientists presume some cloaking technology to be in use. Look out for a way to make the aggressors visible!" failMessage="" completeMessage="" />
+ <hints>
+ <QuestHint id="quest2hint1">
+ <QuestDescription title="The detector beacon" description="Our scientists claim cloaking is generally toggled by a visible Switch called a detector beacon. Try to find a bright light in your Area and approach it!" />
+ </QuestHint>
+ </hints>
+ </GlobalQuest>
+
+ <GlobalQuest id="quest3">
+ <QuestDescription title="Fight their army" description="You have successfully uncovered their civilization and home planet, and it is much worse than we thought... they came prepared! You have to fight their army to fulfill your mission." failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <complete-effects>
+ <AddQuest questId="quest4" />
+ <AddQuest questId="quest4.1" />
+ <AddQuest questId="quest4.2" />
+ <AddQuestHint hintId="quest4.1hint1" />
+ <AddQuestHint hintId="quest4.2hint1" />
+ </complete-effects>
+ </GlobalQuest>
+
+ <GlobalQuest id="quest4">
+ <QuestDescription title="Do the right thing" description="The aggressors have surrendered and seem to have had good reasons for their actions. Yet they did not talk to us beforehand and tried to kill us. What will you do?" failMessage="" completeMessage="" />
+ <hints>
+ </hints>
+ <subquests>
+ <GlobalQuest id="quest4.1">
+ <QuestDescription title="> Destroy their civilisation" description="Even if they had reasons, they are still murderers and can not be trusted anymore. This whole thing might even be a setup... We need to kill them and destroy their planet!" failMessage="" completeMessage="" />
+ <hints>
+ <QuestHint id="quest4.1hint1">
+ <QuestDescription title="Choosing" description="To make this choice, kill the remaining enemy ships. The divisions will follow your decision." />
+ </QuestHint>
+ </hints>
+ </GlobalQuest>
+ <GlobalQuest id="quest4.2">
+ <QuestDescription title="> Spare them and leave" description="Military tension arising from a missunderstanding is no valid reasoning for a genocide. Nothing is. We should leave and talk this out later." failMessage="" completeMessage="" />
+ <hints>
+ <QuestHint id="quest4.2hint1">
+ <QuestDescription title="Choosing" description="To make this choice, fly out of the sector. The divisions will follow your decision." />
+ </QuestHint>
+ </hints>
+ </GlobalQuest>
+ </subquests>
+ </GlobalQuest>
+
+ <!--EVENTS AND TRIGGERS
+ Usable events and triggers:
+ spawntrigger
+ -->
+
+ <EventMultiTrigger name="spawntrigger" activations=1>
+ <events>
+ <trigger>
+ <EventListener event="playerSpawn" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <EventMultiTrigger name="spawned" stayactive=true activations=1>
+ <events>
+ <trigger>
+ <EventListener event="spawntrigger" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <DistanceTrigger name="reachedSector" position="<?lua printC(cSector) ?>" distance="<?lua print(radSector) ?>" target="SpaceShip" beaconMode="identify" targetname="Commander" stayactive=true />
+
+ <EventMultiTrigger name="addQuest2">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=10 >
+ <events>
+ <trigger>
+ <EventListener event="reachedSector" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <DistanceTrigger name="alliesReachedWait" position="<?lua printC(cAllyWait) ?>" distance="1000" target="SpaceShip" beaconMode="identify" targetname="Ally" stayactive=true />
+
+ <!-- So the allies stall when they reached their position for negociation and don“t fire away... -->
+
+ <EventDispatcher name="allyControllerDispatcher">
+ <targets>
+ <EventTarget target="allyController" />
+ </targets>
+ <events>
+ <activity>
+ <Trigger mode=or>
+ <EventTrigger invert=true>
+ <events>
+ <trigger>
+ <EventListener event="alliesReachedWait" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <EventTrigger>
+ <events>
+ <trigger>
+ <EventListener event="noMercy" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <Trigger mode=and>
+ <EventTrigger>
+ <events>
+ <trigger>
+ <EventListener event="fightBegun" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <EventTrigger invert=true>
+ <events>
+ <trigger>
+ <EventListener event="oneUnitLeft" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </Trigger>
+ </Trigger>
+ </activity>
+ </events>
+ </EventDispatcher>
+
+ <EventMultiTrigger name="hintBeacon">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=70 >
+ <events>
+ <trigger>
+ <EventListener event="reachedSector" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <DistanceTrigger name="cloakBeacon" position="<?lua printC(cBeacon) ?>" distance=100 target="SpaceShip" beaconMode="identify" targetname="Commander" stayactive=true />
+
+ <EventMultiTrigger name="fightBegun" stayactive=true>
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=12>
+ <events>
+ <trigger>
+ <EventListener event="cloakBeacon" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <EventDispatcher name="enemyControllerDispatcher">
+ <targets>
+ <EventTarget target="enemyController" />
+ </targets>
+ <events>
+ <activity>
+ <Trigger mode=and>
+ <EventTrigger>
+ <events>
+ <trigger>
+ <EventListener event="fightBegun" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <EventTrigger invert=true>
+ <events>
+ <trigger>
+ <EventListener event="oneUnitLeft" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </Trigger>
+ </activity>
+ </events>
+ </EventDispatcher>
+
+ <EventMultiTrigger name="noMercy" stayactive=true>
+ <events>
+ <trigger>
+ <EventListener event="allUnitsDown" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <EventMultiTrigger name="enemyPlanetMulti">
+ <events>
+ <trigger>
+ <EventListener event="enemyPlanet" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <!-- Recursive helper function for the event at the "end" of a Unit.-->
+ <?lua
+ function enemyTriggerRecursor(i, k)
+ if i > 0 then
+ return [[
+ <EventTrigger name=killedEnemy]] .. ((k-1)*4+i) .. [[ activations=1 stayactive=true delay=0.1>
+ <events>
+ <trigger>
+ <EventListener event=enemy]] .. k .. [[ />
+ </trigger>
+ </events>
+ ]] .. enemyTriggerRecursor(i-1, k) .. [[
+ </EventTrigger>
+ ]]
+ else return ""
+ end
+ end
+ ?>
+ <!-- Actual recursive Event(s) for the respective Units. (packs of 4 Enemies that is!) -->
+ <?lua
+ for k = 1, enemies, 1
+ do
+ print(enemyTriggerRecursor(4,k))
+ ?>
+ <EventMultiTrigger name="unit<?lua print(k) ?>Down" delay=0.1 stayactive=true>
+ <events>
+ <trigger>
+ <EventListener event="killedEnemy<?lua print(k*4) ?>" />
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+ <?lua end ?>
+
+ <EventMultiTrigger name="oneUnitLeft" stayactive=true>
+ <events>
+ <trigger>
+ <Trigger mode=or>
+ <?lua
+ for k = 1, enemies, 1
+ do
+ ?>
+ <Trigger mode=and>
+ <EventTrigger invert=true>
+ <events>
+ <trigger>
+ <EventListener event="unit<?lua print(k) ?>Down" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <?lua
+ for i = 1, enemies, 1
+ do
+ if not (i == k) then
+ ?>
+ <EventTrigger>
+ <events>
+ <trigger>
+ <EventListener event="unit<?lua print(i) ?>Down" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <?lua end end ?>
+ </Trigger>
+ <?lua end ?>
+ </Trigger>
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <EventMultiTrigger name="allUnitsDown" stayactive=true>
+ <events>
+ <trigger>
+ <Trigger mode=and>
+ <?lua
+ for k = 1, enemies, 1
+ do
+ ?>
+ <EventTrigger>
+ <events>
+ <trigger>
+ <EventListener event="unit<?lua print(k) ?>Down" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <?lua end ?>
+ </Trigger>
+ </trigger>
+ </events>
+ </EventMultiTrigger>
+
+ <!--TODO: Complete the DistanceTriggers for completing/succeeding correctly! -->
+
+ <DistanceTrigger active=false invert=true name="almostLeft" position="<?lua printC(cSector) ?>" distance="<?lua print(radSector-200) ?>" target="SpaceShip" beaconMode="identify" targetname="Commander" stayactive=true>
+ <events>
+ <activity>
+ <Trigger mode=and>
+ <EventTrigger>
+ <events>
+ <trigger>
+ <EventListener event="oneUnitLeft" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <EventTrigger invert=true>
+ <events>
+ <trigger>
+ <EventListener event="enemyPlanetMulti" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </Trigger>
+ </activity>
+ </events>
+ </DistanceTrigger>
+
+ <DistanceTrigger active=false invert=true name="leftSector" position="<?lua printC(cSector) ?>" distance="<?lua print(radSector) ?>" target="SpaceShip" beaconMode="identify" targetname="Commander" stayactive=true>
+ <events>
+ <activity>
+ <EventListener event="oneUnitLeft" />
+ </activity>
+ </events>
+ </DistanceTrigger>
+
+ <Script code="Mission endMission true" onLoad="false">
+ <events>
+ <trigger>
+ <EventListener event="leftSector" />
+ </trigger>
+ </events>
+ </Script>
+
+ <!--QUEST EFFECT BEACONS -->
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <AddQuest questId="quest1" />
+ <AddQuestHint HintId="quest1hint1" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="spawntrigger" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest1" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="reachedSector" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <AddQuest questId="quest2" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="addQuest2" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <AddQuestHint hintId="quest2hint1
+ " />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="hintBeacon" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest2" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="cloakBeacon" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <AddQuest questId="quest3" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="fightBegun" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest3" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="oneUnitLeft" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+ <!--TODO: Include planet destruction and quitting -->
+
+ <QuestEffectBeacon times=1>
+ <effects>
+ <CompleteQuest questId="quest4" />
+ </effects>
+ <events>
+ <execute>
+ <EventListener event="enemyAllGone" />
+ </execute>
+ </events>
+ </QuestEffectBeacon>
+
+
+ <!--NOTIFICATIONS -->
+
+ <SimpleNotification broadcast="true" message="Welcome, Commander. It is time to retaliate!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=4 >
+ <events>
+ <trigger>
+ <EventListener event="spawntrigger" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Get to section 5C and erradicate the aggressors!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=8 >
+ <events>
+ <trigger>
+ <EventListener event="spawntrigger" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="That seems extreme. Is there no way around it?">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=12 >
+ <events>
+ <trigger>
+ <EventListener event="spawntrigger" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Stick to your objective, Commander. This is war.">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=16 >
+ <events>
+ <trigger>
+ <EventListener event="spawntrigger" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Huh?! The sector is empty! where are they hiding?">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=2 >
+ <events>
+ <trigger>
+ <EventListener event="reachedSector" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="They must be cloaking themselves! But we'll figure it out...">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=6 >
+ <events>
+ <trigger>
+ <EventListener event="reachedSector" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Got it! Look out for a bright light and touch it!">
+ <events>
+ <trigger>
+ <EventListener event="addQuest2" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Divisions are standing by, Sir.">
+ <events>
+ <trigger>
+ <EventListener event="alliesReachedWait" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Woah! what the hell! they boobytrapped us!">
+ <events>
+ <trigger>
+ <EventListener event="cloakBeacon" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Greetings, Humans. Are you here to resign to your menace and make amends?">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=4 >
+ <events>
+ <trigger>
+ <EventListener event="cloakBeacon" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Menace? What is he on about, General?">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=8 >
+ <events>
+ <trigger>
+ <EventListener event="cloakBeacon" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="None of your concern, Commander. Launch the attack!">
+ <events>
+ <trigger>
+ <EventTrigger stayactive="true" delay=12 >
+ <events>
+ <trigger>
+ <EventListener event="cloakBeacon" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Unit 1 down!">
+ <events>
+ <trigger>
+ <EventListener event="unit1Down" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Unit 2 down!">
+ <events>
+ <trigger>
+ <EventListener event="unit2Down" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Unit 3 down!">
+ <events>
+ <trigger>
+ <EventListener event="unit3Down" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Unit 4 down!">
+ <events>
+ <trigger>
+ <EventListener event="unit4Down" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Please! No More! We surrender!">
+ <events>
+ <trigger>
+ <EventListener event="oneUnitLeft" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Roger that, Commander. We destroy their planet.">
+ <events>
+ <trigger>
+ <EventListener event="allUnitsDown" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="Well done, Commander! Now exfiltrate the sector!">
+ <events>
+ <trigger>
+ <EventListener event="enemyPlanetMulti" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <SimpleNotification broadcast="true" message="This will have dire consequences, Commander!">
+ <events>
+ <trigger>
+ <EventListener event="almostLeft" />
+ </trigger>
+ </events>
+ </SimpleNotification>
+
+ <!--ELEMENTS -->
+
+ <!-- Billboard Path to Sector 5C. Height changes in an atan shape -->
+
+ <?lua
+ for i = 1, 11, 1
+ do
+ heightNow = cPathToEntry[1][2] - (cPathToEntry[1][2]-cSectorEntry[2])*(math.atan(-1.6+0.3*i) + 1)/2
+ cBillNow = {(cSectorEntry[1]-cPathToEntry[1][1])*i/12, heightNow, (cSectorEntry[3]-cPathToEntry[1][3])*i/12}
+ cPathToEntry[i+1] = cBillNow
+ ?>
+ <Billboard position="<?lua printC(cBillNow) ?>" scale=2 material="Flares/ringflare" colour="0.2,0.9,0.2"/>
+ <?lua
+ end
+ cPathToEntry[13] = cSectorEntry
+ ?>
+
+ <Billboard position="<?lua printC(cSectorEntry) ?>" scale=5 material="Flares/ringflare" colour="0.2,0.9,0.2"/>
+
+ <!-- Circular Billboard Ring around Sector 5C -->
+
+ <?lua
+ for i = 1, 64, 1
+ do
+ rBillboard = {math.sin(i*math.pi/32)*radSector, 0, math.cos(i*math.pi/32)*radSector}
+ cBillNow = addC(cSector,rBillboard)
+ ?>
+ <Billboard position="<?lua printC(cBillNow) ?>" scale=10 material="Flares/lensflare" colour="1,0.2,0.2"/>
+ <?lua end ?>
+
+ <!-- Cloaking Beacon -->
+
+ <BlinkingBillboard visible=false active=false scale=2 position="<?lua printC(cBeacon) ?>" material="Flares/lensflare" frequency=1 amplitude=3 colour="0.4,0.4,1">
+ <events>
+ <activity>
+ <EventListener event="addQuest2" />
+ </activity>
+ <visibility>
+ <EventListener event="addQuest2" />
+ </visibility>
+ </events>
+ </BlinkingBillboard>
+
+ <!-- Asteroids you have to fly through to get to the EnemyBase -->
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidField(cField1[1], cField1[2], cField1[3], 20, 30, 4500, 500, 0)
+ ?>
+
+ <!-- Other Asteroid-Fields -->
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidField(cField2[1], cField2[2], cField2[3], 20, 30, 4500, 500, 0)
+ ?>
+
+ <!-- Planets -->
+
+ <Planet
+ position="<?lua printC(cPlanet1) ?>"
+ scale="3000"
+ collisionType="dynamic"
+ linearDamping="0.8"
+ angularDamping="0"
+ mass="5000000"
+ pitch="0"
+ mesh="planets/muunilinst.mesh"
+ atmosphere="atmosphere1"
+ rotationaxis="1,0,0"
+ rotationrate="1.0"
+ atmospheresize="80.0f"
+ imagesize="1024.0f"
+ collisiondamage = 2
+ enablecollisiondamage = true
+ visible=true
+ active=true
+ >
+ <attached>
+ <ForceField position="0,0,0" mode="sphere" diameter="6000" velocity="-500" />
+ </attached>
+ <collisionShapes>
+ <SphereCollisionShape radius="3000" position="0,0,0" />
+ </collisionShapes>
+ </Planet>
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidBelt(cPlanet1[1], cPlanet1[2], cPlanet1[3], 30, 20, 100, 20, 40, 3400, 3700, 400, 1)
+ ?>
+
+ <Planet
+ position="<?lua printC(cPlanet2) ?>"
+ scale="2000"
+ collisionType="dynamic"
+ linearDamping="0.8"
+ angularDamping="0"
+ mass="5000000"
+ pitch="0"
+ mesh="planets/ganymede.mesh"
+ atmosphere="atmosphere1"
+ rotationaxis="1,0,0"
+ rotationrate="1.0"
+ atmospheresize="80.0f"
+ imagesize="1024.0f"
+ collisiondamage = 2
+ enablecollisiondamage = true
+ visible=true
+ active=true
+ >
+ <attached>
+ <ForceField position="0,0,0" mode="sphere" diameter="4000" velocity="-500" />
+ </attached>
+ <collisionShapes>
+ <SphereCollisionShape radius="2000" position="0,0,0" />
+ </collisionShapes>
+ </Planet>
+
+ <?lua
+ dofile("includes/asteroidField.lua")
+ asteroidBelt(cPlanet2[1], cPlanet2[2], cPlanet2[3], 30, 20, 100, 20, 40, 3400, 3700, 400, 1)
+ ?>
+
+ <!-- EnemyPlanet -->
+
+ <Planet
+ position="<?lua printC(cEnemyBasePlanet) ?>"
+ scale="5000"
+ collisionType="dynamic"
+ linearDamping="0.8"
+ angularDamping="0"
+ mass="5000000"
+ pitch="0"
+ mesh="planets/jupiter.mesh"
+ atmosphere="atmosphere1"
+ rotationaxis="1,0,0"
+ rotationrate="1.0"
+ atmospheresize="80.0f"
+ imagesize="1024.0f"
+ collisiondamage = 2
+ enablecollisiondamage = true
+ visible=false
+ active=false
+ >
+ <attached>
+ <ForceField position="0,0,0" rotationaxis="0.1,1,0.1"mode="sphere" diameter="10000" velocity="-500" />
+ </attached>
+ <events>
+ <activity>
+ <Trigger name="enemyPlanetVisible" mode=and>
+ <EventTrigger>
+ <events>
+ <trigger>
+ <EventListener event="cloakBeacon" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <EventTrigger invert=true>
+ <events>
+ <trigger>
+ <EventListener event="enemyPlanetMulti" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </Trigger>
+ </activity>
+ <visibility>
+ <Trigger name="enemyPlanetVisible" mode=and>
+ <EventTrigger>
+ <events>
+ <trigger>
+ <EventListener event="cloakBeacon" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ <EventTrigger invert=true>
+ <events>
+ <trigger>
+ <EventListener event="enemyPlanetMulti" />
+ </trigger>
+ </events>
+ </EventTrigger>
+ </Trigger>
+ </visibility>
+ </events>
+ <collisionShapes>
+ <SphereCollisionShape position="0,0,0" radius=5000/>
+ </collisionShapes>
+ </Planet>
+
+ <!-- Pawn that represents the planet during destruction -->
+
+ <Pawn team=1 visible=false active=false scale=5000 health=500 name="enemyPlanet" position="<?lua printC(cEnemyBasePlanet) ?>" collisionType=dynamic mass=5000000 radarname="Enemy home planet">
+ <events>
+ <activity>
+ <EventListener event="allUnitsDown" />
+ </activity>
+ <visibility>
+ <EventListener event="allUnitsDown" />
+ </visibility>
+ </events>
+ <collisionShapes>
+ <SphereCollisionShape position="0,0,0" radius=5005/>
+ </collisionShapes>
+ </Pawn>
+ <!--SHIPS -->
+ <!-- one Controller to rule them all -->
+ <Pawn position = "100000, 100000, 100000">
+ <controller>
+ <MasterController>
+ </MasterController>
+ </controller>
+ </Pawn>
+ <!--Allied units-->
+
+ <?lua
+ for i = 1, allies, 1
+ do
+ rUnit = {-math.sin(math.pi*((i-1/2)/allies))*125, math.pow(-1,i)*80, math.cos(math.pi*((i-1/2)/allies))*800}
+ cAllyNow = addC(cAlly,rUnit)
+ ?>
+
+ <SpaceShip health=600 initialhealth=600 maxhealth=600 position="<?lua printC(cAllyNow) ?>" name="ally<?lua print(i) ?>.D">
+ <templates>
+ <Template link=ally />
+ </templates>
+ <controller>
+ <DivisionController name="allyController" team=0 formationMode="diamond" spread=100>
+ <actionpoints>
+ <?lua
+ for i = 1, 13, 1
+ do
+ ?>
+ <Actionpoint position="<?lua printC(addC(cPathToEntry[i], rUnit)) ?>" action="fly"/>
+ <?lua end ?>
+ </actionpoints>
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip health=600 initialhealth=600 maxhealth=600 position="<?lua printC(addC(cAllyNow,rSection)) ?>" lookat="0,0,0" name="ally<?lua print(i) ?>.S">
+ <templates>
+ <Template link=ally />
+ </templates>
+ <controller>
+ <SectionController name="allyController" team=0>
+ </SectionController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip health=600 initialhealth=600 maxhealth=600 position="<?lua printC(addC(cAllyNow,rWingman1)) ?>" lookat="0,0,0" name="ally<?lua print(i) ?>.W1">
+ <templates>
+ <Template link=ally />
+ </templates>
+ <controller>
+ <WingmanController name="allyController" team=0>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip health=600 initialhealth=600 maxhealth=600 position="<?lua printC(addC(cAllyNow,rWingman2)) ?>" lookat="0,0,0" name="ally<?lua print(i) ?>.W2">
+ <templates>
+ <Template link=ally />
+ </templates>
+ <controller>
+ <WingmanController name="allyController" team=0>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+
+ <?lua end ?>
+
+ <!-- Enemy Units -->
+
+ <?lua
+ for k = 1, enemies, 1
+ do
+ rUnit = {125 -math.sin(math.pi*((k-1/2)/enemies))*200, math.pow(-1,k)*300, math.cos(math.pi*((k-1/2)/enemies))*1000}
+ cEnemyNow = addC(cEnemy,rUnit)
+ ?>
+
+ <SpaceShip health=400 initialhealth=400 maxhealth=400 position="<?lua printC(cEnemyNow) ?>" name="enemy<?lua print(k) ?>">
+ <templates>
+ <Template link=enemy />
+ </templates>
+ <events>
+ <activity>
+ <EventListener event="cloakBeacon" />
+ </activity>
+ <visibility>
+ <EventListener event="cloakBeacon" />
+ </visibility>
+ </events>
+ <controller>
+ <DivisionController name="enemyController" active=false team=1 formationMode="diamond" spread=100>
+ <actionpoints>
+ <Actionpoint position="<?lua printC(cEnemyNow) ?>" action="fightall" />
+ </actionpoints>
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip health=400 initialhealth=400 maxhealth=400 position="<?lua printC(addC(cEnemyNow,rSection)) ?>" name="enemy<?lua print(k) ?>">
+ <templates>
+ <Template link=enemy />
+ </templates>
+ <events>
+ <activity>
+ <EventListener event="cloakBeacon" />
+ </activity>
+ <visibility>
+ <EventListener event="cloakBeacon" />
+ </visibility>
+ </events>
+ <controller>
+ <SectionController name="enemyController" active=false team=1>
+ </SectionController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip health=400 initialhealth=400 maxhealth=400 position="<?lua printC(addC(cEnemyNow,rWingman1)) ?>" lookat="0,0,0" name="enemy<?lua print(k) ?>">
+ <templates>
+ <Template link=enemy />
+ </templates>
+ <events>
+ <activity>
+ <EventListener event="cloakBeacon" />
+ </activity>
+ <visibility>
+ <EventListener event="cloakBeacon" />
+ </visibility>
+ </events>
+ <controller>
+ <WingmanController name="enemyController" active=false team=1>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+
+ <SpaceShip health=400 initialhealth=400 maxhealth=400 position="<?lua printC(addC(cEnemyNow,rWingman2)) ?>" name="enemy<?lua print(k) ?>">
+ <templates>
+ <Template link=enemy />
+ </templates>
+ <events>
+ <activity>
+ <EventListener event="cloakBeacon" />
+ </activity>
+ <visibility>
+ <EventListener event="cloakBeacon" />
+ </visibility>
+ </events>
+ <controller>
+ <WingmanController name="enemyController" active=false team=1>
+ </WingmanController>
+ </controller>
+ </SpaceShip>
+
+ <?lua end ?>
+
+ </Scene>
+</Level>
Copied: code/branches/presentationHS15/data/levels/templates/spaceshipShuttle.oxt (from rev 10967, code/branches/campaignHS15/data/levels/templates/spaceshipShuttle.oxt)
===================================================================
--- code/branches/presentationHS15/data/levels/templates/spaceshipShuttle.oxt (rev 0)
+++ code/branches/presentationHS15/data/levels/templates/spaceshipShuttle.oxt 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,101 @@
+<Template name=spaceshipShuttle>
+ <SpaceShip
+ hudtemplate = spaceshiphud
+ camerapositiontemplate = spaceshipTransportercameras
+ spawnparticlesource = "Orxonox/fairytwirl"
+ spawnparticleduration = 3
+ explosionchunks = 6
+
+ health = 2000
+ maxhealth = 2500
+ initialhealth = 2000
+
+ primaryThrust = 120;
+ auxilaryThrust = 20;
+ rotationThrust = 30;
+
+ collisionType = "dynamic"
+ mass = 1000
+ linearDamping = 0.7
+ angularDamping = 0.9999999
+ >
+ <engines>
+ <MultiStateEngine position=" 0, 0, 0" template=spaceshipTransporterengine />
+ </engines>
+ <attached>
+ <Model position="0,0,0" yaw=180 pitch=0 roll=0 scale=10 mesh="Transporterspaceship.mesh" />
+ </attached>
+ <collisionShapes>
+ <BoxCollisionShape position=" 0, 0, 20" halfExtents=" 37, 25, 80" />
+ <BoxCollisionShape position=" 0, 21, 20" halfExtents=" 37, 21, 80" />
+ <BoxCollisionShape position=" 0, 40, 110" halfExtents=" 20, 10, 40" />
+ <BoxCollisionShape position=" 0, 45, 170" halfExtents=" 33, 25, 20" />
+ <BoxCollisionShape position=" -60, 33, 0" halfExtents=" 24, 16, 120" />
+ <BoxCollisionShape position=" 60, 33, 0" halfExtents=" 24, 16, 120" />
+ <BoxCollisionShape position=" 0, 10, -90" halfExtents=" 30, 25, 30" />
+ <BoxCollisionShape position=" 0, -3, -145" halfExtents=" 20, 20, 30" />
+ </collisionShapes>
+
+<?lua
+ include("../includes/weaponSettingsTransporter.oxi")
+?>
+ </SpaceShip>
+</Template>
+
+<Template name=spaceshipTransportercameras defaults=0>
+ <SpaceShip>
+ <camerapositions>
+ <CameraPosition position="0,90,350" drag=true mouselook=true />
+ <CameraPosition position="0,125, 400" drag=true mouselook=true />
+ <CameraPosition position="0,200,550" drag=true mouselook=true />
+ </camerapositions>
+ </SpaceShip>
+</Template>
+
+<Template name=spaceshipTransporterengine baseclass=MultiStateEngine>
+ <MultiStateEngine
+ boostfactor = 2
+
+ speedfront = 120
+ speedback = 20
+ speedleftright = 20
+ speedupdown = 20
+
+ defEngineSndNormal = "sounds/Engine_low.ogg"
+ defEngineSndBoost = "sounds/Engine_high.ogg"
+
+ accelerationfront = 40
+ accelerationbrake = 30
+ accelerationback = 20
+ accelerationleftright = 20
+ accelerationupdown = 20
+ >
+ <EffectContainer condition="idle">
+ <WorldSound mainstate="activity" source="sounds/Engine_idle.ogg" looping=1 active=false/>
+ </EffectContainer>
+ <EffectContainer condition="not idle">
+
+ </EffectContainer>
+ <EffectContainer condition="normal or brake">
+
+ </EffectContainer>
+ <EffectContainer condition="normal or boost">
+ <Backlight mainstate=activity active=false scale=2 name=bltest position=" -80, 33, 100" colour="1, 0.7, 0.1, 1.0" width=10 length=3000 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+ <Backlight mainstate=activity active=false scale=2 name=bltest position=" 80, 33, 100" colour="1, 0.7, 0.1, 1.0" width=10 length=3000 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+ <Backlight mainstate=activity active=false scale=2 name=bltest position=" -75, 25, -57" colour="1, 0.7, 0.1, 1.0" width=10 length=3000 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+ <Backlight mainstate=activity active=false scale=2 name=bltest position=" 75, 25, -57" colour="1, 0.7, 0.1, 1.0" width=10 length=3000 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+ </EffectContainer>
+ <EffectContainer condition="boost">
+ <Backlight mainstate=activity active=false scale=3 name=bltest position=" -80, 33, 100" colour="1, 0.7, 0.1, 0.7" width=25 length=2000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+ <Backlight mainstate=activity active=false scale=3 name=bltest position=" 80, 33, 100" colour="1, 0.7, 0.1, 0.7" width=25 length=2000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+ <Backlight mainstate=activity active=false scale=3 name=bltest position=" -75, 25, -57" colour="1, 0.7, 0.1, 0.7" width=25 length=2000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+ <Backlight mainstate=activity active=false scale=3 name=bltest position=" 75, 25, -57" colour="1, 0.7, 0.1, 0.7" width=25 length=2000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+ </EffectContainer>
+ <EffectContainer condition="brake">
+ <FadingBillboard mainstate=activity active=false scale=2 position=" -75, 33, 40" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+ <FadingBillboard mainstate=activity active=false scale=2 position=" 75, 33, 40" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+ <FadingBillboard mainstate=activity active=false scale=1 position=" -68, 25, -115" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+ <FadingBillboard mainstate=activity active=false scale=1 position=" 68, 25, -115" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+ </EffectContainer>
+ </MultiStateEngine>
+</Template>
Modified: code/branches/presentationHS15/src/libraries/util/Math.cc
===================================================================
--- code/branches/presentationHS15/src/libraries/util/Math.cc 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/libraries/util/Math.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -160,7 +160,7 @@
- If the other object is only a bit at my right, the function still returns <tt>Vector2(0.01, 0)</tt>.
- If the other object is exactly above me, the function returns <tt>Vector2(0, 0.5)</tt>.
*/
- orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)
+ orxonox::Vector2 get2DViewCoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)
{
orxonox::Vector3 distance = otherposition - myposition;
Modified: code/branches/presentationHS15/src/libraries/util/Math.h
===================================================================
--- code/branches/presentationHS15/src/libraries/util/Math.h 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/libraries/util/Math.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -90,7 +90,7 @@
_UtilExport float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition);
_UtilExport orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);
- _UtilExport orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);
+ _UtilExport orxonox::Vector2 get2DViewCoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);
_UtilExport orxonox::Vector2 get3DProjection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition, const float mapangle, const float detectionlimit);
_UtilExport bool isObjectHigherThanShipOnMap(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition, const float mapangle);
_UtilExport int determineMap3DZOrder(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition, const float detectionlimit);
Modified: code/branches/presentationHS15/src/modules/docking/DockingController.cc
===================================================================
--- code/branches/presentationHS15/src/modules/docking/DockingController.cc 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/modules/docking/DockingController.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -60,7 +60,7 @@
return;
float distance = (this->dock_->getWorldPosition() - entity->getPosition()).length();
- Vector2 coord = get2DViewcoordinates( // I don't understand this too
+ Vector2 coord = get2DViewCoordinates( // I don't understand this too
entity->getPosition(),
entity->getOrientation() * WorldEntity::FRONT,
entity->getOrientation() * WorldEntity::UP,
Modified: code/branches/presentationHS15/src/modules/overlays/hud/HUDRadar.cc
===================================================================
--- code/branches/presentationHS15/src/modules/overlays/hud/HUDRadar.cc 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/modules/overlays/hud/HUDRadar.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -239,7 +239,7 @@
it->second->_notifyZOrder(this->overlay_->getZOrder() * 100 + 70 + zOrder);
}
else
- coord = get2DViewcoordinates(this->owner_->getPosition(), this->owner_->getOrientation() * WorldEntity::FRONT, this->owner_->getOrientation() * WorldEntity::UP, wePointer->getWorldPosition());
+ coord = get2DViewCoordinates(this->owner_->getPosition(), this->owner_->getOrientation() * WorldEntity::FRONT, this->owner_->getOrientation() * WorldEntity::UP, wePointer->getWorldPosition());
coord *= math::pi / 3.5f; // small adjustment to make it fit the texture
it->second->setPosition((1.0f + coord.x - size) * 0.5f, (1.0f - coord.y - size) * 0.5f);
Modified: code/branches/presentationHS15/src/modules/weapons/weaponmodes/MineGun.cc
===================================================================
--- code/branches/presentationHS15/src/modules/weapons/weaponmodes/MineGun.cc 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/modules/weapons/weaponmodes/MineGun.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -57,6 +57,8 @@
this->setMunitionName("MineMunition");
this->setDefaultSound("sounds/mineactivate.ogg");
+
+ hudImageString_ = "Orxonox/WSHUD_WM_MineGun";
}
MineGun::~MineGun()
Copied: code/branches/presentationHS15/src/orxonox/controllers/ActionpointController.cc (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/ActionpointController.cc)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/ActionpointController.cc (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/ActionpointController.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,767 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#include "ActionpointController.h"
+
+#include "core/XMLPort.h"
+#include <algorithm>
+#include "worldentities/Actionpoint.h"
+namespace orxonox
+{
+
+ RegisterClass(ActionpointController);
+
+ ActionpointController::ActionpointController(Context* context) : FightingController(context)
+ {
+ this->ticks_ = 0;
+ this->bPatrolling_ = false;
+ this->bInLoop_ = false;
+ this->bLoop_ = false;
+ this->bEndLoop_ = false;
+ loopActionpoints_.clear();
+ parsedActionpoints_.clear();
+ actionpoints_.clear();
+ this->bTakenOver_ = false;
+ this->action_ = Action::NONE;
+ this->squaredaccuracy_ = 2500;
+ this->bStartedDodging_ = false;
+ this->bDefaultPatrol_ = true;
+ this->bDefaultFightAll_ = true;
+ this->stop_ = false;
+ RegisterObject(ActionpointController);
+
+ }
+ void ActionpointController::XMLPort( Element& xmlelement, XMLPort::Mode mode )
+ {
+ SUPER( ActionpointController, XMLPort, xmlelement, mode );
+
+ XMLPortObject(ActionpointController, WorldEntity, "actionpoints", addActionpoint, getActionpoint, xmlelement, mode);
+ XMLPortParam(ActionpointController, "defaultFightAll", setDefaultFightAll, getDefaultFightAll, xmlelement, mode).defaultValues(true);
+ XMLPortParam(ActionpointController, "defaultPatrol", setDefaultPatrol, getDefaultPatrol, xmlelement, mode).defaultValues(true);
+ }
+
+ ActionpointController::~ActionpointController()
+ {
+ loopActionpoints_.clear();
+ parsedActionpoints_.clear();
+ actionpoints_.clear();
+
+ }
+ void ActionpointController::tick(float dt)
+ {
+ if (!this || !this->getControllableEntity() || !this->isActive() || this->stop_)
+ return;
+
+ //count ticks, ticks_ is unsigned, so overflow is not a problem
+ ++this->ticks_;
+ if (this->ticks_ == 1)
+ {
+ //those vectors are in reversed order after being set by XML.
+ std::reverse(parsedActionpoints_.begin(), parsedActionpoints_.end());
+ std::reverse(actionpoints_.begin(), actionpoints_.end());
+ }
+
+ if (!this || !this->getControllableEntity())
+ return;
+ //fly
+ if (this->bHasTargetPosition_)
+ {
+ this->moveToTargetPosition(dt);
+ }//or just rotate
+ else if (this->bLookAtTarget_)
+ {
+ this->lookAtTarget(dt);
+ }
+
+
+ if (!this || !this->getControllableEntity())
+ return;
+ //don't fire rocket each tick
+ if (timeout_ <= 0)
+ {
+ this->bFiredRocket_ = false;
+ }
+ else if (this->bFiredRocket_)
+ {
+ --this->timeout_;
+ }
+
+ if (!this || !this->getControllableEntity())
+ return;
+ //sometimes dodge, sometimes attack
+ if (this->ticks_ % 80 <= 10)
+ {
+ this->bDodge_ = false;
+ }
+ else
+ {
+ this->bDodge_ = true;
+ }
+
+ if (!this || !this->getControllableEntity())
+ return;
+ //fire if you can
+ if (this->bShooting_)
+ {
+ this->doFire();
+ }
+ SUPER(ActionpointController, tick, dt);
+ }
+
+ /**
+ @brief
+ action() manages the state machine.
+ */
+
+ void ActionpointController::action()
+ {
+ if (!this || !this->getControllableEntity() || !this->isActive())
+ return;
+
+ //deltaHp is used to know if this got attacked
+ this->deltaHp = orxonox_cast<Pawn*> (this->getControllableEntity())->getHealth() - this->previousHp;
+ this->previousHp = orxonox_cast<Pawn*> (this->getControllableEntity())->getHealth();
+
+ //look out for enemies
+ if (this->bDefaultPatrol_ || (this->action_ != Action::FLY && this->action_ != Action::NONE))
+ {
+ this->startAttackingEnemiesThatAreClose();
+ }
+ if (!this || !this->getControllableEntity())
+ return;
+
+ //No action -> pop one from stack
+ if (this->action_ == Action::NONE || this->bTakenOver_)
+ {
+ //if default behaviour is fighting all, push it onto the stack
+ if (this->parsedActionpoints_.empty() && this->loopActionpoints_.empty() && this->bDefaultFightAll_)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ Point p = { Action::FIGHTALL, "", Vector3::ZERO, false };
+ this->parsedActionpoints_.push_back (p);
+ }
+ if (!this || !this->getControllableEntity())
+ return;
+ this->executeActionpoint();
+ if (!this || !this->getControllableEntity())
+ return;
+ this->bTakenOver_ = false;
+ }
+ if (!this || !this->getControllableEntity())
+ return;
+
+ //Action fightall -> fight till nobody alive
+ if (this->action_ == Action::FIGHTALL)
+ {
+
+ if (!this->hasTarget())
+ {
+ ControllableEntity* newTarget = this->closestTarget();
+ if (newTarget)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->setAction (Action::FIGHTALL, newTarget);
+ }
+ else
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->nextActionpoint();
+ if (!this || !this->getControllableEntity())
+ return;
+ this->executeActionpoint();
+
+ }
+ }
+ }
+ //Action fight -> fight as long as enemies in range
+ else if (this->action_ == Action::FIGHT)
+ {
+ if (!this->hasTarget() )
+ {
+ //----find a target----
+ ControllableEntity* newTarget = this->closestTarget();
+ if (!this || !this->getControllableEntity())
+ return;
+ if (newTarget &&
+ CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->setAction (Action::FIGHT, newTarget);
+ }
+ else
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->nextActionpoint();
+ if (!this || !this->getControllableEntity())
+ return;
+ this->executeActionpoint();
+ }
+ }
+ else if (this->hasTarget())
+ {
+ //----fly in formation if far enough----
+ Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition();
+
+ if (diffVector.length() > this->attackRange_)
+ {
+ ControllableEntity* newTarget = this->closestTarget();
+ if (!this || !this->getControllableEntity())
+ return;
+ if (newTarget &&
+ CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->setAction (Action::FIGHT, newTarget);
+ }
+ else
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->nextActionpoint();
+ if (!this || !this->getControllableEntity())
+ return;
+ this->executeActionpoint();
+ }
+ }
+ }
+ }
+ else if (this->action_ == Action::FLY)
+ {
+ if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->nextActionpoint();
+ if (!this || !this->getControllableEntity())
+ return;
+ this->executeActionpoint();
+ }
+ }
+ else if (this->action_ == Action::PROTECT)
+ {
+ if (!this->getProtect())
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->nextActionpoint();
+ if (!this || !this->getControllableEntity())
+ return;
+ this->executeActionpoint();
+ }
+ if (!this || !this->getControllableEntity())
+ return;
+ this->stayNearProtect();
+ }
+ else if (this->action_ == Action::ATTACK)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ if (!this->hasTarget())
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->nextActionpoint();
+ if (!this || !this->getControllableEntity())
+ return;
+ this->executeActionpoint();
+ }
+ }
+ }
+ /**
+ @brief
+ if action is protect, this follows protect_ and fights enemies that are close
+ */
+ void ActionpointController::setProtect (ControllableEntity* protect)
+ {
+ this->protect_ = protect;
+ }
+ ControllableEntity* ActionpointController::getProtect ()
+ {
+ return this->protect_;
+ }
+ //XML method
+ void ActionpointController::addActionpoint(WorldEntity* actionpoint)
+ {
+ std::string actionName;
+ Vector3 position;
+ std::string targetName;
+ bool inLoop = false;
+ Point p;
+ if (actionpoint->getIdentifier()->getName() == "Actionpoint")
+ {
+ Actionpoint* ap = orxonox_cast<Actionpoint*> (actionpoint);
+ actionName = ap->getActionXML();
+ targetName = ap->getName();
+ position = ap->getWorldPosition();
+
+ if (this->bEndLoop_)
+ {
+ this->bInLoop_ = false;
+ }
+ if (!this->bInLoop_ && ap->getLoopStart())
+ {
+ this->bInLoop_ = true;
+ }
+ if (this->bInLoop_ && ap->getLoopEnd())
+ {
+ this->bEndLoop_ = true;
+ }
+ inLoop = this->bInLoop_;
+
+ Action::Value value;
+
+ if ( actionName == "FIGHT" )
+ { value = Action::FIGHT; }
+ else if ( actionName == "FLY" )
+ { value = Action::FLY; }
+ else if ( actionName == "PROTECT" )
+ { value = Action::PROTECT; }
+ else if ( actionName == "NONE" )
+ { value = Action::NONE; }
+ else if ( actionName == "FIGHTALL" )
+ { value = Action::FIGHTALL; }
+ else if ( actionName == "ATTACK" )
+ { value = Action::ATTACK; }
+ else
+ ThrowException( ParseError, std::string( "Attempting to set an unknown Action: '" )+ actionName + "'." );
+ p.action = value; p.name = targetName; p.position = position; p.inLoop = inLoop;
+ }
+ else
+ {
+ inLoop = true;
+ p.action = Action::FLY; p.name = ""; p.position = actionpoint->getWorldPosition(); p.inLoop = inLoop;
+ }
+ parsedActionpoints_.push_back(p);
+ this->actionpoints_.push_back(actionpoint);
+ }
+ //XML method
+ WorldEntity* ActionpointController::getActionpoint(unsigned int index) const
+ {
+ if (index < this->actionpoints_.size())
+ return this->actionpoints_[index];
+ else
+ return 0;
+ }
+ //XML method
+ Action::Value ActionpointController::getAction ()
+ {
+ return this->action_;
+ }
+ //XML method
+ std::string ActionpointController::getActionName()
+ {
+ switch ( this->action_ )
+ {
+ case Action::FIGHT:
+ { return "FIGHT"; }
+ case Action::FLY:
+ { return "FLY"; }
+ case Action::PROTECT:
+ { return "PROTECT"; }
+ case Action::NONE:
+ { return "NONE"; }
+ case Action::FIGHTALL:
+ { return "FIGHTALL"; }
+ case Action::ATTACK:
+ { return "ATTACK"; }
+ default:
+ return "NONE";
+ break;
+ }
+ }
+ //XML method
+ void ActionpointController::setAction (Action::Value action)
+ {
+ this->action_ = action;
+ }
+ //set action and target/protect
+ void ActionpointController::setAction (Action::Value action, ControllableEntity* target)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->action_ = action;
+ if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
+ {
+ if (target)
+ this->setTarget (target);
+ }
+ else if (action == Action::PROTECT)
+ {
+ if (target)
+ this->setProtect (target);
+ }
+ }
+ //set action and target position
+ void ActionpointController::setAction (Action::Value action, const Vector3& target)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->action_ = action;
+ if (action == Action::FLY)
+ {
+ this->setTargetPosition (target);
+ }
+ }
+ //set action and target position and orientation
+ void ActionpointController::setAction (Action::Value action, const Vector3& target, const Quaternion& orient )
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->action_ = action;
+ if (action == Action::FLY)
+ {
+ this->setTargetPosition (target);
+ this->setTargetOrientation (orient);
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ //------------------------------Actionpoint methods-----------------------------
+ //------------------------------------------------------------------------------
+
+ //POST: this starts doing what was asked by the last element of parsedActionpoints_,
+ //if last element was failed to be parsed, next element will be executed.
+ void ActionpointController::executeActionpoint()
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+
+ Point p;
+ if (this->bLoop_ && !loopActionpoints_.empty())
+ {
+ p = loopActionpoints_.back();
+ }
+ else if (this->bLoop_)
+ {
+ this->bLoop_ = false;
+ return;
+ }
+ else if (!this->bLoop_ && !parsedActionpoints_.empty())
+ {
+ p = parsedActionpoints_.back();
+ }
+ else
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+
+ this->setTarget(0);
+ this->setTargetPosition(this->getControllableEntity()->getWorldPosition());
+ this->action_ = Action::NONE;
+ return;
+ }
+ if (!this || !this->getControllableEntity())
+ return;
+ if (!this->bLoop_ && this->parsedActionpoints_.back().inLoop)
+ {
+ //MOVES all points that are in loop to a loop vector
+ this->fillLoop();
+ if (!this || !this->getControllableEntity())
+ return;
+ this->bLoop_ = true;
+ executeActionpoint();
+ return;
+ }
+ if (!this || !this->getControllableEntity())
+ return;
+ this->setAction (p.action);
+ if (!this || !this->getControllableEntity())
+ return;
+
+ switch (this->action_)
+ {
+ case Action::FIGHT:
+ {
+ std::string targetName = p.name;
+ if (targetName == "")
+ break;
+ for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ if (CommonController::getName(*itP) == targetName)
+ {
+ this->setTarget (static_cast<ControllableEntity*>(*itP));
+ }
+ }
+ break;
+ }
+ case Action::FLY:
+ {
+ this->setTargetPosition( p.position );
+ if (!this || !this->getControllableEntity())
+ return;
+ if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->nextActionpoint();
+ if (!this || !this->getControllableEntity())
+ return;
+ this->executeActionpoint();
+ }
+ break;
+ }
+ case Action::PROTECT:
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+
+ std::string protectName = p.name;
+ if (protectName == "reservedKeyword:human")
+ {
+ for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+ {
+ if (orxonox_cast<ControllableEntity*>(*itP) && ((*itP)->getController()) && ((*itP)->getController()->getIdentifier()->getName() == "NewHumanController"))
+ {
+ this->setProtect (static_cast<ControllableEntity*>(*itP));
+ }
+ }
+ }
+ else
+ {
+ for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+ {
+ if (CommonController::getName(*itP) == protectName)
+ {
+ this->setProtect (static_cast<ControllableEntity*>(*itP));
+ }
+ }
+ }
+ if (!this->getProtect())
+ {
+ this->nextActionpoint();
+ this->executeActionpoint();
+ }
+ break;
+ }
+ case Action::NONE:
+ {
+ break;
+ }
+ case Action::FIGHTALL:
+ {
+ break;
+ }
+ case Action::ATTACK:
+ {
+ std::string targetName = p.name;
+
+ for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+ {
+ if (CommonController::getName(*itP) == targetName)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->setTarget (static_cast<ControllableEntity*>(*itP));
+ }
+ }
+ if (!this->hasTarget())
+ {
+ this->nextActionpoint();
+ if (!this || !this->getControllableEntity())
+ return;
+ this->executeActionpoint();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ //calculate where in world coordinates this ship has to be, so that it keeps distance to protect_, and fly there
+ void ActionpointController::stayNearProtect()
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+
+ Vector3 targetRelativePosition(0, 300, 300);
+ if (!this->getProtect())
+ {
+ this->nextActionpoint();
+ return;
+ }
+ Vector3 targetAbsolutePosition = ((this->getProtect()->getWorldPosition()) +
+ (this->getProtect()->getWorldOrientation()* (targetRelativePosition)));
+ this->setTargetPosition(targetAbsolutePosition);
+ if (!this->getProtect())
+ {
+ this->nextActionpoint();
+ return;
+ }
+ this->setTargetOrientation(this->getProtect()->getWorldOrientation());
+ }
+ //remove current point from the stack
+ void ActionpointController::nextActionpoint()
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ if (this->bLoop_)
+ {
+ if (this->bPatrolling_)
+ {
+ this->loopActionpoints_.pop_back();
+ this->bPatrolling_ = false;
+ }
+ else if (!this->loopActionpoints_.empty())
+ {
+ this->moveBackToTop();
+ }
+ }
+ else
+ {
+ if (!this->parsedActionpoints_.empty())
+ {
+ this->parsedActionpoints_.pop_back();
+ }
+ }
+ this->setAction(Action::NONE);
+ this->bHasTargetPosition_ = false;
+ }
+ //if looping, instead of erasing point, move it to the top (back is what gets executed, so it's kinda reversed stack)
+ void ActionpointController::moveBackToTop()
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+
+ Point temp = loopActionpoints_.back();
+ loopActionpoints_.pop_back();
+ std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
+ loopActionpoints_.push_back(temp);
+ std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
+ }
+ //POST: moves all consecutive points that are in loop to the loop stack
+ void ActionpointController::fillLoop()
+ {
+ loopActionpoints_.clear();
+ fillLoopReversed();
+ std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
+ }
+ void ActionpointController::fillLoopReversed()
+ {
+ if (parsedActionpoints_.back().inLoop)
+ {
+ loopActionpoints_.push_back(parsedActionpoints_.back());
+ parsedActionpoints_.pop_back();
+ }
+ if (parsedActionpoints_.back().inLoop)
+ {
+ fillLoopReversed();
+ }
+ }
+ //copy other ship's stacks so that if it dies, this can finish that ship's actions
+ void ActionpointController::takeActionpoints (const std::vector<Point>& vector, const std::vector<Point>& loop, bool b)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->parsedActionpoints_ = vector;
+ if (!this || !this->getControllableEntity())
+ return;
+ this->loopActionpoints_ = loop;
+ this->bLoop_ = b;
+ this->bTakenOver_ = true;
+ }
+ //attack closest target
+ void ActionpointController::setClosestTarget()
+ {
+ this->setTarget (static_cast<ControllableEntity*>( closestTarget() ) );
+ }
+ //find closest target
+ Pawn* ActionpointController::closestTarget()
+ {
+ if (!this || !this->getControllableEntity())
+ return 0;
+
+ Pawn* closestTarget = 0;
+ float minDistance = std::numeric_limits<float>::infinity();
+ Gametype* gt = this->getGametype();
+ for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+ {
+ if (!this || !this->getControllableEntity())
+ return 0;
+ if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
+ continue;
+
+ float distance = CommonController::distance (*itP, this->getControllableEntity());
+ if (distance < minDistance)
+ {
+ closestTarget = *itP;
+ minDistance = distance;
+ }
+ }
+ if (closestTarget)
+ {
+ return closestTarget;
+ }
+ return 0;
+ }
+ //push action FIGHT to the stack and set target to the closest enemy
+ void ActionpointController::startAttackingEnemiesThatAreClose()
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+
+ //if (this->action_ != Action::FIGHT && this->action_ != Action::FIGHTALL)
+ {
+ if (!this->target_ || (this->target_ && CommonController::distance (this->getControllableEntity(), this->target_) > this->attackRange_))
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ Pawn* newTarget = this->closestTarget();
+ if ( newTarget &&
+ CommonController::distance (this->getControllableEntity(), static_cast<ControllableEntity*>(newTarget))
+ <= this->attackRange_ )
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ this->setTarget(newTarget);
+ if (this->bLoop_ && !this->bPatrolling_)
+ {
+ Point p = { Action::FIGHT, "", Vector3::ZERO, true };
+ this->loopActionpoints_.push_back(p);
+ }
+ else if (!this->bPatrolling_)
+ {
+ //orxout (internal_error) << "found new target " << CommonController::getName(newTarget) <<endl;
+ Point p = { Action::FIGHT, "", Vector3::ZERO, false };
+ this->parsedActionpoints_.push_back(p);
+ }
+ this->bPatrolling_ = true;
+ this->executeActionpoint();
+ }
+ }
+ }
+ }
+}
Copied: code/branches/presentationHS15/src/orxonox/controllers/ActionpointController.h (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/ActionpointController.h)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/ActionpointController.h (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/ActionpointController.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,262 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#ifndef _ActionpointController_H__
+#define _ActionpointController_H__
+
+#include "controllers/FightingController.h"
+#include "tools/Timer.h"
+#include "tools/interfaces/Tickable.h"
+#include "../modules/pickup/PickupSpawner.h"
+#include <map>
+
+#include <boost/shared_ptr.hpp>
+
+
+namespace orxonox
+{
+ /**
+ @brief
+ ActionpointController is a state machine with states:
+ 1) NONE
+ 2) FLY: fly towards a point
+ 3) FIGHT: fight enemies that are in attackRange_ (see FightingController)
+ 4) PROTECT: follow this->protect_
+ 5) FIGHTALL: fight all enemies on the map
+ 6) ATTACK: fight a specific spaceship
+ This controller always executes an action that is in the back of the vector being used.
+ After current this->action_ is completed, next action becomes the top action (one that will
+ be returned by someVector.back()), and current action either will be removed (if not looping),
+ or moved to the top (if looping).
+
+ Every second action(), which is once in two seconds, this searches the area for enemies that are in attack range, if finds anyone,
+ pushes Action::FIGHT to the stack. That makes spaceship fight enemies inside of a sphere, and when all enemies in range are dead,
+ Action::FIGHT is removed from the stack, and spaceship resumes doing whatever action was being executed before.
+
+ In XML one has to attack Actionpoints in order to achieve any complex behaviour, but in Controller all actionpoints are effectively
+ being stored in an array of type Point::Value.
+ @note
+ ActionpointController will not work, if there is no MasterController in the level!
+ */
+ namespace Action
+ {
+ enum Value
+ {
+ NONE, FLY, FIGHT, PROTECT, FIGHTALL, ATTACK
+ };
+
+ }
+
+ struct Point {
+ Action::Value action;
+ std::string name;
+ Vector3 position;
+ bool inLoop;
+ } ;
+ namespace PickupType
+ {
+ enum Value
+ {
+ NONE, DAMAGE, HEALTH, SPEED, PORTAL
+ };
+ }
+
+ class _OrxonoxExport ActionpointController : public FightingController, public Tickable
+ {
+ public:
+
+ ActionpointController(Context* context);
+ virtual ~ActionpointController();
+ virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+ /**
+ @brief
+ tick is called every tick by Game (?).
+ In tick ship flies and fires.
+ */
+ virtual void tick(float dt);
+ /**
+ @brief
+ XML method, example XML usage:
+ <SpaceShip position="-2000, 1500, -1000" lookat="0,0,0" team=0 name="ss2">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=0 formationMode="finger4">
+ <actionpoints>
+ <Actionpoint position="0,0,0" action="FLY" />
+ <Actionpoint position="-1000,750,-500" action="ATTACK" attack="attack" />
+ <Actionpoint position="-1000,750,-500" action="PROTECt" protectMe=true />
+ <Actionpoint position="-1000,750,-500" action="PROTECt" protect="protect" />
+ <Actionpoint position="-1000,750,-500" action="FIGHTALL" />
+ </actionpoints>
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+
+ Full description:
+ Adds an Actionpoint to this->actionpoints_. Actionpoint can take arguments like action="attack" attack="name".
+ For documentation on Actionpoint XML arguments, check out Actionpoint.h class
+ If any WorldEntity that is not Actionpoint or its child being sent to actionpoints through XML,
+ action would be assumed to be Action::FLY and target position to be position of the entity. Also, if not Actionpoint
+ is passed, it is assumed to be in a loop. How it works is: in <actionpoints> first all Actionpoints between
+ first Actionpoint with loopStart=true and first following Actionpoint with loopEnd=true are included in a single loop.
+ If they are adjacent (in the input array) with WorldEntity, then WorldEntity is also in a loop.
+ All the Worldentities are assumed to be in loop.
+
+ Loop example:
+ <SpaceShip position="-1500, 1500, -1000" lookat="0,0,0" team=0 name="ss1">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=0 formationMode="wall">
+ <actionpoints>
+ <Actionpoint position=" 0,2000,-600" action="FLY" loopStart=true/>
+ <Actionpoint position=" 0,2000,-1000" action="FLY" />
+ <Actionpoint position="400,2000,-1000" action="FLY" />
+ <Actionpoint position="400,2000,-600" action="FLY" loopEnd=true />
+ </actionpoints>
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+
+ other loop example:
+ <SpaceShip position="-1500, -1500, -1500" lookat="0,0,0" team=0 name="ss1">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=0 formationMode="diamond">
+ <actionpoints>
+ <Model mesh="cube.mesh" scale=8 position=" 0,2000,-600" />
+ <Model mesh="cube.mesh" scale=8 position=" 0,2000,-1000" />
+ <Model mesh="cube.mesh" scale=8 position="400,2000,-1000" />
+ <Model mesh="cube.mesh" scale=8 position="400,2000,-600" />
+ </actionpoints>
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+
+ @note
+ Don't use several loops, and don't use WorldEntities as input to <actionpoints> as I didn't test it well, but you
+ can try if feeling lucky.
+ */
+ void addActionpoint(WorldEntity* actionpoint);
+ WorldEntity* getActionpoint(unsigned int index) const;
+ void setDefaultFightAll(bool value)
+ { this->bDefaultFightAll_ = value; }
+ bool getDefaultFightAll ()
+ { return this->bDefaultFightAll_; }
+ void setDefaultPatrol(bool value)
+ { this->bDefaultPatrol_ = value; }
+ bool getDefaultPatrol ()
+ { return this->bDefaultPatrol_; }
+
+
+ virtual void stayNearProtect();
+ virtual void action(); //<! action() is called in regular intervals managing the bot's behaviour. Only gets called by MasterController
+ virtual void takeActionpoints (const std::vector<Point>& vector, const std::vector<Point>& loop, bool b);
+
+ virtual Action::Value getAction ();
+ virtual std::string getActionName();
+
+ void setAction (Action::Value action);
+ void setAction (Action::Value action, ControllableEntity* target);
+ void setAction (Action::Value action, const Vector3& target);
+ void setAction (Action::Value action, const Vector3& target, const Quaternion& orient );
+
+ virtual bool setWingman(ActionpointController* wingman)
+ { return false; }
+ virtual bool hasWingman()
+ { return true; }
+ virtual bool setFollower(ActionpointController* myFollower)
+ { return false; }
+ virtual bool hasFollower()
+ { return true; }
+
+
+ protected:
+ void startAttackingEnemiesThatAreClose();
+ WeakPtr<ActionpointController> myWingman_;
+ WeakPtr<ActionpointController> myFollower_;
+ WeakPtr<ActionpointController> myDivisionLeader_;
+ //----[Actionpoint information]----
+ Action::Value action_;
+ std::string protectName_;
+ std::string targetName_;
+ std::vector<WeakPtr<WorldEntity> > actionpoints_;
+ float squaredaccuracy_;
+ std::vector<Point > parsedActionpoints_;//<! actionpoints as they are stored here after being parsed from XML
+ std::vector<Point > loopActionpoints_; //<! actionpoints that are to be looped
+ bool bInLoop_;
+ bool bLoop_; //<! is state machine looping?
+ bool bEndLoop_;
+ bool bTakenOver_; //<! are actionpoints taken over from the leader when he died? if yes, top actionpoint
+ //<! is to be executed for the state machine to start working
+ //----[/Actionpoint information]----
+ void setProtect (ControllableEntity* protect);
+ ControllableEntity* getProtect ();
+ WeakPtr<ControllableEntity> protect_; //<! entity that is to be protected if this->action_ == Action::PROTECT
+ void fillLoop(); //<! moves actionpoints that are should be in loop from parsedActionpoints_ to loopActionpoints_
+ void fillLoopReversed();
+ void moveBackToTop(); //<! analog of removing back actionpoint for loopActionpoints_: instead of removing it,
+ //<! move it to the top, so that it will be executed later on.
+ void setClosestTarget();
+ Pawn* closestTarget();
+ //----[Actionpoint methods]----
+ /**
+ @brief
+ Sets this->target_, this->targetPosition_, this->protect_ and this->action_ depending
+ on the current actionpoint in the vector parsedActionpoints_ if not looping or
+ loopActionpoints_ if looping.
+ @note
+ */
+ void executeActionpoint();
+ /**
+ @brief
+ If this->bLoop_, move back action to top (back is the current one, top is the last),
+ otherwise remove back actionpoint.
+ @note
+ actionpoints_ is only used for XML, real state stacks are parsedActionpoints_ and loopActionpoints_
+ */
+ void nextActionpoint();
+ //----[Actionpoint methods]----
+
+ bool bDefaultFightAll_;
+
+ bool bPatrolling_;
+ bool bDefaultPatrol_;
+ bool stop_;
+ unsigned int ticks_; //<! local tick counter
+
+ };
+}
+
+#endif /* _ActionpointController_H__ */
Modified: code/branches/presentationHS15/src/orxonox/controllers/CMakeLists.txt
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/CMakeLists.txt 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/orxonox/controllers/CMakeLists.txt 2015-12-11 14:26:20 UTC (rev 10970)
@@ -10,4 +10,12 @@
DroneController.cc
FormationController.cc
ControllerDirector.cc
+ DivisionController.cc
+ WingmanController.cc
+ SectionController.cc
+ CommonController.cc
+ ActionpointController.cc
+ FlyingController.cc
+ FightingController.cc
+ MasterController.cc
)
Copied: code/branches/presentationHS15/src/orxonox/controllers/CommonController.cc (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/CommonController.cc)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/CommonController.cc (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/CommonController.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,218 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option)any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * Dominik Solenicki
+ *
+ */
+#include "controllers/CommonController.h"
+
+//here starts stuff for sameTeam function copied from FormationController
+#include "gametypes/TeamDeathmatch.h"
+#include "gametypes/Gametype.h"
+#include "controllers/DroneController.h"
+#include "gametypes/Dynamicmatch.h"
+
+#include "worldentities/pawns/TeamBaseMatchBase.h"
+
+namespace orxonox
+{
+
+ RegisterClass(CommonController);
+ CommonController::CommonController(Context* context): Controller(context)
+ {
+ RegisterObject(CommonController);
+ }
+ CommonController::~CommonController()
+ {
+ //no member variables - nothing to destroy
+ }
+ /**
+ @brief
+ PRE: a < b.
+ returns random float between a and b.
+ */
+ float CommonController::randomInRange(float a, float b)
+ {
+ return a + rnd(1.0f) * (b - a);
+ }
+ /**
+ @brief
+ returns distance between two entities, if either is zero pointer, returns infinity
+ */
+ float CommonController::distance (const ControllableEntity* entity1, const ControllableEntity* entity2)
+ {
+ if (!entity1 || !entity2)
+ return std::numeric_limits<float>::infinity();
+ return (entity1->getPosition() - entity2->getPosition()).length();
+ }
+ /**
+ @brief
+ bad function from FormationController that returns true if both entities have same team
+ */
+ bool CommonController::sameTeam (ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)
+ {
+ //uncomment following code if functions stops working due to being a hack
+ /*if (!entity1 || !entity2)
+ return false;
+ return entity1->getTeam() == entity2->getTeam();*/
+ if (!entity1 || !entity2)
+ return false;
+ if (entity1 == entity2)
+ return true;
+
+ int team1 = entity1->getTeam();
+ int team2 = entity2->getTeam();
+
+ Controller* controller = 0;
+ if (entity1->getController())
+ controller = entity1->getController();
+ else
+ controller = entity1->getXMLController();
+ if (controller)
+ {
+ if (controller->getIdentifier()->getName() == "MasterController")
+ return true;
+ CommonController* ac = orxonox_cast<CommonController*>(controller);
+ if (ac)
+ team1 = ac->getTeam();
+ }
+
+ if (entity2->getController())
+ controller = entity2->getController();
+ else
+ controller = entity2->getXMLController();
+ if (controller)
+ {
+ if (controller->getIdentifier()->getName() == "MasterController")
+ return true;
+ CommonController* ac = orxonox_cast<CommonController*>(controller);
+ if (ac)
+ team2 = ac->getTeam();
+ }
+
+ TeamGametype* tdm = orxonox_cast<TeamGametype*>(gametype);
+ if (tdm)
+ {
+ if (entity1->getPlayer())
+ team1 = tdm->getTeam(entity1->getPlayer());
+
+ if (entity2->getPlayer())
+ team2 = tdm->getTeam(entity2->getPlayer());
+ }
+
+ TeamBaseMatchBase* base = 0;
+ base = orxonox_cast<TeamBaseMatchBase*>(entity1);
+ if (base)
+ {
+ switch (base->getState())
+ {
+ case BaseState::ControlTeam1:
+ team1 = 0;
+ break;
+ case BaseState::ControlTeam2:
+ team1 = 1;
+ break;
+ case BaseState::Uncontrolled:
+ default:
+ team1 = -1;
+ }
+ }
+ base = orxonox_cast<TeamBaseMatchBase*>(entity2);
+ if (base)
+ {
+ switch (base->getState())
+ {
+ case BaseState::ControlTeam1:
+ team2 = 0;
+ break;
+ case BaseState::ControlTeam2:
+ team2 = 1;
+ break;
+ case BaseState::Uncontrolled:
+ default:
+ team2 = -1;
+ }
+ }
+
+ DroneController* droneController = 0;
+ droneController = orxonox_cast<DroneController*>(entity1->getController());
+ if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2)
+ return true;
+ droneController = orxonox_cast<DroneController*>(entity2->getController());
+ if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1)
+ return true;
+ DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController());
+ DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController());
+ if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner())
+ return true;
+
+ Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype);
+ if (dynamic)
+ {
+ if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;}
+
+ if (entity1->getPlayer())
+ team1 = dynamic->getParty(entity1->getPlayer());
+
+ if (entity2->getPlayer())
+ team2 = dynamic->getParty(entity2->getPlayer());
+
+ if (team1 ==-1 ||team2 ==-1) {return false;}
+ else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;}
+ else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;}
+ else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;}
+ else return true;
+ }
+
+ return (team1 == team2 && team1 != -1);
+ }
+ /**
+ @brief
+ returns true if entityThatLooks does look at entityBeingLookeAt with a tolerance of angle.
+ */
+ bool CommonController::isLooking(const ControllableEntity* entityThatLooks, const ControllableEntity* entityBeingLookedAt, float angle)
+ {
+ if (!entityThatLooks || !entityBeingLookedAt)
+ return false;
+ return (getAngle(entityThatLooks ->getPosition() ,
+ entityThatLooks->getOrientation() * WorldEntity::FRONT,
+ entityBeingLookedAt->getWorldPosition()) < angle);
+ }
+ /**
+ @brief
+ returns a name of a Pawn entity, if no name set, returns string representing address of the Pawn.
+ */
+ std::string CommonController::getName(const Pawn* entity)
+ {
+ std::string name = entity->getName();
+ if (name == "")
+ {
+ const void * address = static_cast<const void*>(entity);
+ std::stringstream ss;
+ ss << address;
+ name = ss.str();
+ }
+ return name;
+ }
+}
Copied: code/branches/presentationHS15/src/orxonox/controllers/CommonController.h (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/CommonController.h)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/CommonController.h (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/CommonController.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,59 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * Dominik Solenicki
+ *
+ */
+
+#ifndef _CommonController_H__
+#define _CommonController_H__
+
+
+#include "controllers/Controller.h" //that's what I inherit from
+
+#include <limits> //I use limits pretty much in every class, so might as well include it in the parent class
+
+#include "worldentities/ControllableEntity.h" //same for ControllableEntity
+#include "worldentities/pawns/Pawn.h" //and Pawn
+
+
+namespace orxonox
+{
+ class _OrxonoxExport CommonController : public Controller
+ {
+
+ public:
+ static const float hardcoded_projectile_speed = 750; //<! FightingController uses it to predict enemy position
+
+ CommonController(Context* context);
+ virtual ~CommonController();
+ static float randomInRange(float a, float b);
+ static float distance(const ControllableEntity* entity1, const ControllableEntity* entity2);
+ static bool sameTeam (ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gt);
+ static bool isLooking(const ControllableEntity* entityThatLooks, const ControllableEntity* entityBeingLookedAt, float angle ) ;
+ static std::string getName(const Pawn* entity ) ;
+ };
+}
+
+#endif /* _CommonController_H__ */
Copied: code/branches/presentationHS15/src/orxonox/controllers/DivisionController.cc (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/DivisionController.cc)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/DivisionController.cc (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/DivisionController.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,147 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#include "DivisionController.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+
+ RegisterClass(DivisionController);
+
+ //Leaders share the fact that they have Wingmans
+ DivisionController::DivisionController(Context* context) : ActionpointController(context)
+ {
+ RegisterObject(DivisionController);
+ this->setFormationMode(FormationMode::DIAMOND);
+ this->target_ = 0;
+ this->myFollower_ = 0;
+ this->myWingman_ = 0;
+ }
+
+ DivisionController::~DivisionController()
+ {
+ for (size_t i = 0; i < this->actionpoints_.size(); ++i)
+ {
+ if(this->actionpoints_[i])
+ this->actionpoints_[i]->destroy();
+ }
+ this->parsedActionpoints_.clear();
+ this->actionpoints_.clear();
+ }
+
+ void DivisionController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+ {
+ SUPER(DivisionController, XMLPort, xmlelement, mode);
+
+ }
+ void DivisionController::tick(float dt)
+ {
+ if (!this->isActive())
+ return;
+
+ SUPER(DivisionController, tick, dt);
+
+ }
+ void DivisionController::action()
+ {
+ if (!this || !this->getControllableEntity() || !this->isActive())
+ return;
+
+ ActionpointController::action();
+ if (!this || !this->getControllableEntity())
+ return;
+ if (!(this->parsedActionpoints_.empty() && this->loopActionpoints_.empty()))
+ {
+ if (this->myFollower_)
+ {
+ this->myFollower_->takeActionpoints(this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+ }
+ else if (this->myWingman_)
+ {
+ this->myWingman_->takeActionpoints(this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+ }
+ }
+
+
+ }
+ //I wanted to do it different here, but at this point I think nothing will change if I delete that method
+ void DivisionController::stayNearProtect()
+ {
+ ActionpointController::stayNearProtect();
+ }
+
+ bool DivisionController::setWingman(ActionpointController* newWingman)
+ {
+ if (!this->myWingman_)
+ {
+ this->myWingman_ = newWingman;
+ if (!this->hasFollower())
+ newWingman->takeActionpoints (this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ bool DivisionController::setFollower(ActionpointController* newFollower)
+ {
+ if (!this->myFollower_)
+ {
+ this->myFollower_ = newFollower;
+ if (this->hasWingman())
+ {
+ this->myWingman_->takeActionpoints (std::vector<Point>(), std::vector<Point>(), false);
+ }
+
+ newFollower->takeActionpoints (this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ bool DivisionController::hasWingman()
+ {
+ if (this->myWingman_)
+ return true;
+ else
+ return false;
+ }
+ bool DivisionController::hasFollower()
+ {
+ if (this->myFollower_)
+ return true;
+
+ return false;
+ }
+
+}
Copied: code/branches/presentationHS15/src/orxonox/controllers/DivisionController.h (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/DivisionController.h)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/DivisionController.h (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/DivisionController.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,78 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#ifndef _DivisionController_H__
+#define _DivisionController_H__
+
+#include "controllers/ActionpointController.h"
+
+
+
+namespace orxonox
+{
+ /**
+ @note
+ ActionpointController will not work, if there is no MasterController in the level!
+ */
+ class _OrxonoxExport DivisionController : public ActionpointController
+ {
+ public:
+ //----[language demanded functions]----
+ DivisionController(Context* context);
+
+ virtual ~DivisionController();
+ //----[/language demanded functions]----
+
+ //----[orxonox demanded functions]----
+ virtual void tick(float dt);
+
+ virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+ //----[orxonox demanded functions]----
+
+ //----[own functions]----
+ virtual bool setFollower(ActionpointController* newFollower);
+ virtual bool setWingman(ActionpointController* newWingman);
+ virtual bool hasWingman();
+ virtual bool hasFollower();
+
+ //----[/own functions]----
+ virtual void stayNearProtect();
+
+ protected:
+ //----action must only be managed by this----
+ virtual void action(); //<! action() is called in regular intervals managing the bot's behaviour.
+
+ private:
+ //----private variables-----
+ Timer actionTimer_; //<! Regularly calls action().
+
+
+ };
+}
+
+#endif /* _DivisionController_H__ */
Copied: code/branches/presentationHS15/src/orxonox/controllers/FightingController.cc (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/FightingController.cc)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/FightingController.cc (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/FightingController.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,377 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or ( at your option )any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * Fabian 'x3n' Landau, Dominik Solenicki
+ *
+ */
+#include "controllers/FightingController.h"
+#include "core/XMLPort.h"
+#include "util/Math.h"
+
+
+#include "worldentities/pawns/SpaceShip.h"
+
+#include "weaponsystem/WeaponMode.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/Weapon.h"
+#include "weaponsystem/WeaponSlot.h"
+#include "weaponsystem/WeaponSystem.h"
+#include "weaponsystem/Munition.h"
+
+namespace orxonox
+{
+
+ RegisterClass (FightingController);
+
+ FightingController::FightingController( Context* context ): FlyingController( context )
+ {
+ this->attackRange_ = 2500;
+ this->stopLookingAtTarget();
+ this->bSetupWorked = false;
+ this->timeout_ = 0;
+ RegisterObject( FightingController );
+ }
+ FightingController::~FightingController()
+ {
+
+ }
+ void FightingController::XMLPort( Element& xmlelement, XMLPort::Mode mode )
+ {
+ SUPER( FightingController, XMLPort, xmlelement, mode );
+ }
+ void FightingController::lookAtTarget(float dt)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+ ControllableEntity* entity = this->getControllableEntity();
+ if ( !entity )
+ return;
+ Vector2 coord = get2DViewCoordinates
+ ( entity->getPosition() ,
+ entity->getOrientation() * WorldEntity::FRONT,
+ entity->getOrientation() * WorldEntity::UP,
+ positionOfTarget_ );
+
+ //rotates should be in range [-1,+1], clamp cuts off all that is not
+ float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );
+ float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );
+
+ //Yaw and Pitch are enough to start facing the target
+ this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt );
+ this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt );
+ }
+ void FightingController::stopLookingAtTarget()
+ {
+ this->bLookAtTarget_ = false;
+ }
+ void FightingController::startLookingAtTarget()
+ {
+ this->bLookAtTarget_ = true;
+ }
+ bool FightingController::hasTarget() const
+ {
+ if ( this->target_ )
+ return true;
+ return false;
+ }
+
+ void FightingController::setTarget( ControllableEntity* target )
+ {
+ this->target_ = target;
+ if ( this->target_ )
+ {
+ this->setPositionOfTarget( target_->getWorldPosition() );
+ }
+ }
+ void FightingController::setPositionOfTarget( const Vector3& target )
+ {
+ this->positionOfTarget_ = target;
+ this->bHasPositionOfTarget_ = true;
+ }
+ void FightingController::setOrientationOfTarget( const Quaternion& orient )
+ {
+ this->orientationOfTarget_=orient;
+ this->bHasOrientationOfTarget_=true;
+ }
+
+ void FightingController::maneuver()
+ {
+ if ( !this->target_ || !this->getControllableEntity())
+ return;
+
+
+ Vector3 thisPosition = this->getControllableEntity()->getWorldPosition();
+ this->setPositionOfTarget(this->target_->getWorldPosition());
+ //this->setOrientationOfTarget(this->target_->getOrientation());
+ Vector3 diffVector = this->positionOfTarget_ - thisPosition;
+ float diffLength = diffVector.length();
+ Vector3 diffUnit = diffVector/diffLength;
+
+ if (!this || !this->getControllableEntity())
+ return;
+
+ //too far? well, come closer then
+ if (diffLength > this->attackRange_)
+ {
+ this->spread_ = 400;
+ this->formationMode_ = FormationMode::DIAMOND;
+ this->bKeepFormation_ = true;
+
+ this->setTargetPosition(this->positionOfTarget_ - diffUnit * 100.0f);
+ }
+ else
+ {
+ bool bTargetIsLookingAtThis = CommonController::isLooking (this->target_, this->getControllableEntity(), math::pi/20.0f)
+ || this->deltaHp < 0;
+ this->bKeepFormation_ = false;
+
+ if (!this || !this->getControllableEntity())
+ return;
+ if (!this->bDodge_)
+ {
+ // orxout(internal_error) << "attacking" << endl;
+ this->bStartedDodging_ = false;
+
+ this->setTargetPosition(this->positionOfTarget_ - diffUnit * 50.0f);
+ return;
+ }
+ else if (bTargetIsLookingAtThis || diffLength < 700.0f)
+ {
+ // orxout(internal_error) << "dodging" << endl;
+ if (!this->bStartedDodging_)
+ {
+ this->bStartedDodging_ = true;
+ dodge(thisPosition, diffLength, diffUnit);
+ }
+ }
+ else
+ {
+ if (diffLength < 1000)
+ {
+ // orxout(internal_error) << "looking" << endl;
+ this->stopMoving();
+ this->startLookingAtTarget();
+
+ }
+ else
+ {
+ // orxout(internal_error) << "closing up" << endl;
+ this->setTargetPosition(this->positionOfTarget_ - diffUnit * 300.0f);
+ }
+ }
+ }
+ }
+
+ void FightingController::dodge(const Vector3& thisPosition, float diffLength, Vector3& diffUnit)
+ {
+ //d.x*x + d.y*y + d.z*z == 0
+ //z = 1/d.z * (-d.y*y - d.x * x)
+ float x = CommonController::randomInRange (300, 800) * (CommonController::randomInRange(0,1) <= 0.5 ? 1 : -1);
+ float y = CommonController::randomInRange (300, 800) * (CommonController::randomInRange(0,1) <= 0.5 ? 1 : -1);
+ float z = diffUnit.z == 0 ? 0 : (1/diffUnit.z) * (-x * diffUnit.x - y * diffUnit.y);
+ if (diffLength < 150.0f)
+ {
+ this->setTargetPosition(this->positionOfTarget_ + Vector3(z,x,y));
+ }
+ else
+ {
+ this->setTargetPosition(thisPosition + Vector3(x,y,z) + (this->deltaHp < 0 ? -diffUnit * 450.0f :
+ (diffLength < 700.0f ? -diffUnit*700.0f : diffUnit * 50.0f)));
+
+ }
+ this->boostControl();
+
+ }
+ bool FightingController::canFire()
+ {
+ //no target? why fire?
+ if (!this->target_ || !this->getControllableEntity())
+ return false;
+ Vector3 newPositionOfTarget = getPredictedPosition(this->getControllableEntity()->getWorldPosition(),
+ hardcoded_projectile_speed, this->target_->getWorldPosition(),
+ this->target_->getVelocity());
+ if (!this->target_ || !this->getControllableEntity())
+ return false;
+ //Vector3.isNaN() is what I used on my machine and it worked...
+ if (!(std::isnan(newPositionOfTarget.x) || std::isnan(newPositionOfTarget.y) || std::isnan(newPositionOfTarget.z)))
+ {
+ this->setPositionOfTarget(newPositionOfTarget);
+ }
+
+ return squaredDistanceToTarget() < this->attackRange_*this->attackRange_ && this->isLookingAtTarget(math::pi / 20.0f);
+ }
+
+
+ float FightingController::squaredDistanceToTarget() const
+ {
+ if (!this || !this->getControllableEntity())
+ return 0;
+ if (!this->target_ || !this->getControllableEntity())
+ return (this->getControllableEntity()->getPosition().squaredDistance(this->targetPosition_));
+ else
+ return (this->getControllableEntity()->getPosition().squaredDistance(this->positionOfTarget_));
+ }
+ bool FightingController::isLookingAtTarget( float angle ) const
+ {
+ if ( !this->getControllableEntity() || !this->target_ )
+ return false;
+ return CommonController::isLooking(this->getControllableEntity(), this->getTarget(), angle);
+ }
+ void FightingController::setClosestTarget()
+ {
+ this->setTarget (static_cast<ControllableEntity*>( closestTarget() ) );
+ }
+
+ Pawn* FightingController::closestTarget() const
+ {
+ if (!this || !this->getControllableEntity())
+ return 0;
+
+ Pawn* closestTarget = 0;
+ float minDistance = std::numeric_limits<float>::infinity();
+ Gametype* gt = this->getGametype();
+ for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+ {
+ if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
+ continue;
+
+ float distance = CommonController::distance (*itP, this->getControllableEntity());
+ if (distance < minDistance)
+ {
+ closestTarget = *itP;
+ minDistance = distance;
+ }
+ }
+ if (closestTarget)
+ {
+ return closestTarget;
+ }
+ return 0;
+ }
+ //I checked it out, rockets DO NOT cause any problems! this->getControllableEntity() is always a SpaceShip
+ void FightingController::doFire()
+ {
+ if (!this->bSetupWorked)
+ {
+ this->setupWeapons();
+ }
+ if (!this->target_ || !this->getControllableEntity())
+ {
+ return;
+ }
+
+ Pawn* pawn = orxonox_cast<Pawn*> (this->getControllableEntity());
+ if (pawn)
+ pawn->setAimPosition (this->positionOfTarget_);
+
+ int firemode;
+ float distance = CommonController::distance (this->getControllableEntity(), this->target_);
+
+
+
+ if (distance < 1500)
+ {
+ if (this->rocketsLeft_ > 0 && !this->bFiredRocket_)
+ {
+ firemode = getFiremode ("RocketFire");
+ }
+ else
+ {
+ if (distance > 800)
+ firemode = getFiremode ("HsW01");
+ else
+ firemode = getFiremode ("LightningGun");
+ }
+
+ }
+
+
+ else if (distance < 2000)
+ {
+ firemode = getFiremode ("HsW01");
+ }
+ else
+ {
+ firemode = getFiremode ("LightningGun");
+ }
+ if (firemode < 0)
+ {
+ //assuming there is always some weapon with index 0
+ firemode = 0;
+ }
+ if (firemode == getFiremode("RocketFire"))
+ {
+ this->timeout_ = 5;
+ this->rocketsLeft_--;
+ this->bFiredRocket_ = true;
+ }
+ if (firemode == getFiremode("SimpleRocketFire"))
+ {
+ this->rocketsLeft_--;
+ }
+
+ this->getControllableEntity()->fire(firemode);
+
+ }
+ void FightingController::setupWeapons() //TODO: Make this function generic!! (at the moment is is based on conventions)
+ {
+ this->bSetupWorked = false;
+ if(this->getControllableEntity())
+ {
+ Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
+ if(pawn && pawn->isA(Class(SpaceShip))) //fix for First Person Mode: check for SpaceShip
+ {
+ this->weaponModes_.clear(); // reset previous weapon information
+ WeaponSlot* wSlot = 0;
+ for(int l=0; (wSlot = pawn->getWeaponSlot(l)) ; l++)
+ {
+ WeaponMode* wMode = 0;
+ for(int i=0; (wMode = wSlot->getWeapon()->getWeaponmode(i)) ; i++)
+ {
+ std::string wName = wMode->getIdentifier()->getName();
+ // SubclassIdentifier<Munition> munition = ClassByString(wName);
+ if (wName == "RocketFire")
+ this->rocketsLeft_ = 10;
+ // this->rocketsLeft_ = orxonox_cast<Pawn*>(this->getControllableEntity())->getWeaponSystem()->getMunition(&munition)->getNumMunitionInCurrentMagazine(wMode);
+ if(this->getFiremode(wName) == -1) //only add a weapon, if it is "new"
+ weaponModes_[wName] = wMode->getMode();
+ }
+ }
+ if(weaponModes_.size())//at least one weapon detected
+ this->bSetupWorked = true;
+ }//pawn->weaponSystem_->getMunition(SubclassIdentifier< Munition > *identifier)->getNumMunition (WeaponMode *user);
+ }
+
+ }
+
+ int FightingController::getFiremode(std::string name)
+ {
+ for (std::map< std::string, int >::iterator it = this->weaponModes_.begin(); it != this->weaponModes_.end(); ++it)
+ {
+ if (it->first == name)
+ return it->second;
+ }
+ return -1;
+ }
+}
Copied: code/branches/presentationHS15/src/orxonox/controllers/FightingController.h (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/FightingController.h)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/FightingController.h (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/FightingController.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,106 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * Fabian 'x3n' Landau, Dominik Solenicki
+ *
+ */
+
+#ifndef _FightingController_H__
+#define _FightingController_H__
+
+
+#include "controllers/FlyingController.h"
+
+namespace orxonox
+{
+ /**
+ @brief
+ FightingController stores all the fighting methods and member variables of AI.
+ Main methods here are maneuver() and dodge().
+
+ @note
+ ActionpointController will not work, if there is no MasterController in the level!
+ */
+ class _OrxonoxExport FightingController : public FlyingController
+ {
+
+ public:
+ FightingController(Context* context);
+ virtual ~FightingController();
+
+ virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+ float squaredDistanceToTarget() const;
+ bool isLookingAtTarget(float angle) const;
+ bool hasTarget() const;
+ ControllableEntity* getTarget() const
+ { return this->target_; }
+ bool bKeepFormation_; //even if action_ == FIGHT, you might still want to keep formation if far enough form the target
+ virtual void maneuver(); //<! sets this->targetPosition_, which is a Vector3 of where this ship flies. Decision is made based on
+ //<! the distance to enemy, if being attacked, dodge() is called, otherwise ship just flies towards this->target_.
+ bool bShooting_; //<! if true, ship shoots each tick
+ bool canFire(); //<! check if target_ is in radius and if this is looking at target_
+ protected:
+ void setTarget(ControllableEntity* target); //set a target to shoot at
+
+ void setPositionOfTarget(const Vector3& target); //good to know where target is
+ void setOrientationOfTarget(const Quaternion& orient); //I don't really use that
+ void stopLookingAtTarget(); //<! target dead -> you need to be able to fly
+ void startLookingAtTarget(); //<! if close to target, no need to fly, just rotate yourself
+ void lookAtTarget(float dt); //<! rotate yourself towards target
+
+ void dodge(const Vector3& thisPosition, float diffLength, Vector3& diffUnit); //<! choose a random Vector3 perpendicular to the difference vector between
+ //<! this and target_ plus or minus some amount in difference vector direction,
+ //<! depending on whether it is better to close up or survive.
+ void dodgeTowards (Vector3& position); //fly towards position and awoid being hit
+ void doFire(); //<! choose weapon, set aim at target_ and fire
+ WeakPtr<ControllableEntity> target_;
+ void setClosestTarget();
+
+ bool bHasPositionOfTarget_;
+ Vector3 positionOfTarget_;
+ bool bHasOrientationOfTarget_;
+ Quaternion orientationOfTarget_;
+ Pawn* closestTarget() const;
+
+ bool bDodge_;
+ int attackRange_;
+ bool bLookAtTarget_;
+ float deltaHp;
+ float previousHp;
+ bool bStartedDodging_;
+ //WEAPONSYSTEM DATA
+ int rocketsLeft_;
+ int timeout_;
+ bool bFiredRocket_;
+ std::map<std::string, int> weaponModes_; //<! Links each "weapon" to it's weaponmode - managed by setupWeapons()
+ //std::vector<int> projectiles_; //<! Displays amount of projectiles of each weapon. - managed by setupWeapons()
+ void setupWeapons(); //<! Defines which weapons are available for a bot. Is recalled whenever a bot was killed.
+ bool bSetupWorked; //<! If false, setupWeapons() is called.
+ int getFiremode(std::string name);
+
+ };
+}
+
+#endif /* _FightingController_H__ */
Copied: code/branches/presentationHS15/src/orxonox/controllers/FlyingController.cc (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/FlyingController.cc)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/FlyingController.cc (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/FlyingController.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,286 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option)any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+
+ * Co-authors:
+ * ...
+ *
+ */
+#include <OgreMatrix3.h> //for Quaternion manipulations
+
+#include "util/Math.h"
+#include "core/XMLPort.h"
+#include "controllers/FlyingController.h"
+
+#include "worldentities/pawns/SpaceShip.h" //for boosting
+
+namespace orxonox
+{
+ RegisterClass (FlyingController);
+
+ FlyingController::FlyingController(Context* context): CommonController(context)
+ {
+ RegisterObject(FlyingController);
+ this->rotationProgress_ = 0;
+ this->spread_ = 200;
+ this->tolerance_ = 80;
+ this->bCopyOrientation_ = true;
+ }
+ FlyingController::~FlyingController()
+ {
+ }
+
+ void FlyingController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+ {
+ XMLPortParam(FlyingController, "spread", setSpread, getSpread, xmlelement, mode);
+ XMLPortParam(FlyingController, "formationMode", setFormationModeXML, getFormationModeXML, xmlelement, mode);
+ SUPER(FlyingController, XMLPort, xmlelement, mode);
+ }
+
+ void FlyingController::setFormationModeXML(std::string val)
+ {
+ const std::string valUpper = getUppercase(val);
+ FormationMode::Value value;
+
+ if (valUpper == "WALL")
+ value = FormationMode::WALL;
+ else if (valUpper == "FINGER4")
+ value = FormationMode::FINGER4;
+ else if (valUpper == "DIAMOND")
+ value = FormationMode::DIAMOND;
+ else
+ ThrowException(ParseError, std::string("Attempting to set an unknown FormationMode: '")+ val + "'.");
+ this->setFormationMode(value);
+ }
+ std::string FlyingController::getFormationModeXML() const
+ {
+ switch (this->formationMode_)
+ {
+ case FormationMode::WALL:
+ { return "WALL"; }
+ case FormationMode::FINGER4:
+ { return "FINGER4"; }
+ case FormationMode::DIAMOND:
+ { return "DIAMOND"; }
+ default:
+ return "DIAMOND";
+ }
+ }
+ void FlyingController::stopMoving()
+ {
+ this->bHasTargetPosition_ = false;
+ }
+ /**
+ @brief
+ if distance to targetPosition is smaller than this->tolerance_, no moving should be made, otherwise
+ find amount of yaw and pitch that have to be applied, so that ship looks at targetPosition, then
+ ship is moved forward towards targetPosition. Also target orientation is being applied.
+ */
+ void FlyingController::moveToPosition(const Vector3& targetPosition, float dt)
+ {
+ if (!this->getControllableEntity())
+ return;
+ ControllableEntity* entity = this->getControllableEntity();
+
+ float distance = (targetPosition - entity->getPosition()).length();
+
+ if (distance >= this->tolerance_)
+ {
+ //function that calculates how much yaw and pitch are to be applied
+ Vector2 coord = get2DViewCoordinates
+ (entity->getPosition() ,
+ entity->getOrientation() * WorldEntity::FRONT,
+ entity->getOrientation() * WorldEntity::UP,
+ targetPosition);
+ //limit yaw and pitch by [-1,1]
+ float rotateX = -clamp(coord.x * 10, -1.0f, 1.0f);
+ float rotateY = clamp(coord.y * 10, -1.0f, 1.0f);
+
+ if (!entity)
+ return;
+
+ //apply yaw and pitch
+ entity->rotateYaw(ROTATEFACTOR * rotateX * dt);
+ entity->rotatePitch(ROTATEFACTOR * rotateY * dt);
+
+ if (!entity)
+ return;
+
+ //only move either if ship looks at target with a certain tolerance, or if ship is far enough for it to be ok to move in a curve.
+ if (distance > this->tolerance_*1.5f || (rotateX > -0.03 && rotateX < 0.03 && rotateY > -0.03 && rotateY < 0.03))
+ entity->moveFrontBack(SPEED * dt);
+ //roll
+ copyTargetOrientation(dt);
+ }
+ else
+ {
+ bHasTargetPosition_ = false;
+ }
+ }
+ /**
+ @brief
+ fly towards a preset targetPosition_
+ */
+ void FlyingController::moveToTargetPosition(float dt)
+ {
+ this->moveToPosition (this->targetPosition_, dt);
+ }
+ /**
+ @brief
+ roll ship so that it has same roll as orient
+ */
+ void FlyingController::copyOrientation(const Quaternion& orient, float dt)
+ {
+ //copied from
+ //http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Quaternion+and+Rotation+Primer&structure=Tutorials#Q._How_can_I_make_my_objects_rotate_smoothly_You_mentioned_slerp_etc_
+ //how can I make my objects rotate smoothly?
+ if (!this->getControllableEntity())
+ return;
+ Quaternion myOrient = this->getControllableEntity()->getOrientation();
+ this->rotationProgress_ += dt;
+
+ if (this->rotationProgress_ > 1)
+ {
+ this->rotationProgress_ = 0;
+ this->bHasTargetOrientation_ = false;
+ }
+ else
+ {
+ Quaternion deltaOrientation = Quaternion::Slerp(rotationProgress_, myOrient, orient, true);
+
+ Matrix3 deltaMatrix, myMatrix;
+
+ deltaOrientation.ToRotationMatrix(deltaMatrix);
+ myOrient.ToRotationMatrix (myMatrix);
+
+ Radian yawDelta, pitchDelta, rollDelta, yawMy, pitchMy, rollMy;
+ deltaMatrix.ToEulerAnglesYXZ(yawDelta, pitchDelta, rollDelta);
+ myMatrix.ToEulerAnglesYXZ (yawMy, pitchMy, rollMy);
+
+ if (!this->getControllableEntity())
+ return;
+ this->getControllableEntity()->rotateRoll ((rollDelta.valueRadians() - rollMy.valueRadians())*ROTATEFACTOR*dt);
+ }
+ }
+ /**
+ @brief
+ roll ship so that it has same roll as a preset targetOrientation_
+ */
+ void FlyingController::copyTargetOrientation(float dt)
+ {
+ if (bHasTargetOrientation_)
+ {
+ this->copyOrientation(targetOrientation_, dt);
+ }
+ }
+ /**
+ @brief
+ set Vector to fly to
+ */
+ void FlyingController::setTargetPosition(const Vector3& target)
+ {
+ this->targetPosition_ = target;
+ this->bHasTargetPosition_ = true;
+ }
+ /**
+ @brief
+ set orientation to apply
+ */
+ void FlyingController::setTargetOrientation(const Quaternion& orient)
+ {
+ this->targetOrientation_=orient;
+ this->bHasTargetOrientation_=true;
+ }
+ /**
+ @brief
+ set orientation to apply
+ */
+ void FlyingController::setTargetOrientation(ControllableEntity* target)
+ {
+ if (target)
+ this->setTargetOrientation(target->getOrientation());
+ }
+ /**
+ @brief
+ boost if you can
+ */
+ void FlyingController::boostControl()
+ {
+ if (!this->getControllableEntity())
+ return;
+ SpaceShip* ship = orxonox_cast<SpaceShip*>(this->getControllableEntity());
+ if(ship == NULL) return;
+ if(ship->getBoostPower()*1.5f > ship->getInitialBoostPower()) //upper limit ->boost
+ {
+ this->getControllableEntity()->boost(true);
+ }
+ else if(ship->getBoostPower()*4.0f < ship->getInitialBoostPower()) //lower limit ->do not boost
+ {
+ this->getControllableEntity()->boost(false);
+ }
+ }
+ /**
+ @brief
+ keep this ship in a formation with its division
+ */
+ void FlyingController::keepFormation(const ControllableEntity* leaderEntity, Vector3& targetRelativePosition)
+ {
+ if (!this->getControllableEntity())
+ return;
+ ControllableEntity* myEntity = this->getControllableEntity();
+ Vector3 myPosition = myEntity->getWorldPosition();
+
+ if (!leaderEntity)
+ {
+ return;
+ }
+ Quaternion orient = leaderEntity->getWorldOrientation();
+ Vector3 leaderPosition = leaderEntity->getWorldPosition();
+
+ if (!leaderEntity)
+ {
+ return;
+ }
+ //calculate where in world coordinates this ship should fly
+ Vector3 targetAbsolutePosition =
+ (leaderPosition + (orient*WorldEntity::FRONT) * (leaderEntity->getVelocity().length()/5)
+ + (orient* (targetRelativePosition)));
+ //let ship finish rotating. also don't call copyOrientation too often as it is a slow function. Don't know how to do it different
+ if (this->bCopyOrientation_)
+ this->setTargetOrientation (orient);
+ //set a position to fly to
+ this->setTargetPosition (targetAbsolutePosition);
+
+ //boost if too far
+ if ((targetAbsolutePosition - myPosition).length() > this->tolerance_ * 1.5f)
+ {
+ this->boostControl();
+ }
+ else
+ {
+ if (!this->getControllableEntity())
+ return;
+ this->getControllableEntity()->boost(false);
+ }
+ }
+}
Copied: code/branches/presentationHS15/src/orxonox/controllers/FlyingController.h (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/FlyingController.h)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/FlyingController.h (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/FlyingController.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,105 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * Dominik Solenicki
+ *
+ */
+
+#ifndef _FlyingController_H__
+#define _FlyingController_H__
+
+
+#include "controllers/CommonController.h"
+
+namespace orxonox
+{
+ /**
+ @brief
+ FlyingController stores all the flying methods and member variables of AI.
+ */
+
+ //Formation mode for the divisions
+ namespace FormationMode
+ {
+ enum Value
+ {
+ FINGER4, DIAMOND, WALL
+ };
+ }
+
+ class _OrxonoxExport FlyingController : public CommonController
+ {
+
+ public:
+ static const float SPEED = 0.9f/0.02f; //<! ship's speed
+ static const float ROTATEFACTOR = 0.6f/0.02f; //<! ship's rotation factor
+
+ FlyingController(Context* context);
+ virtual ~FlyingController();
+ virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+ void setSpread (int spread) //<! spread is a multiplier for formation flight, should be bigger than 100
+ { this->spread_ = spread; }
+ int getSpread () const
+ { return this->spread_; }
+
+ void setFormationModeXML(std::string val);
+ std::string getFormationModeXML() const;
+
+ void setFormationMode(FormationMode::Value val)
+ { this->formationMode_ = val; }
+ FormationMode::Value getFormationMode() const
+ { return this->formationMode_; }
+ bool bCopyOrientation_; //<! set to true by default, MasterController sets it in its tick(),
+ //<! if true, this will set its leader orientation as target orientation in action()
+ protected:
+ void stopMoving(); //<! don't call moveToTargetPosition() in tick, call lookAtTarget() from FightingController instead
+
+ void moveToPosition(const Vector3& target, float dt); //<! move towards a vector
+ void moveToTargetPosition(float dt); //<! move to the preset position. Don't mix with positionOfTarget!
+
+ void copyOrientation(const Quaternion& orient, float dt); //<! roll to have same roll as orient
+ void copyTargetOrientation(float dt); //<! roll to have a preset orient
+
+ void setTargetPosition(const Vector3& target); //<! preset a Vector to fly to
+ void setTargetOrientation(const Quaternion& orient); //<! preset a desired orientation
+ void setTargetOrientation(ControllableEntity* target); //<! preset a desired orientation
+ virtual void boostControl(); //<! boost if you can
+ void keepFormation (const ControllableEntity* leaderEntity,
+ Vector3& targetRelativePosition); //<! preset targetPosition, so that
+ //<! this stays in a certain position relative to leader
+
+ FormationMode::Value formationMode_;
+
+ float rotationProgress_; //<! for slerping
+ bool bHasTargetPosition_;
+ Vector3 targetPosition_; //<! vector to fly to
+ bool bHasTargetOrientation_;
+ Quaternion targetOrientation_; //<! orientation to take
+ int spread_; //<! spread is a multiplier for formation flight, should be bigger than 100
+ int tolerance_; //<! if this ship is tolerance_ away from targetPosition_, ship decides that it finished moving
+ };
+}
+
+#endif /* _FlyingController_H__ */
Modified: code/branches/presentationHS15/src/orxonox/controllers/FormationController.cc
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/FormationController.cc 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/orxonox/controllers/FormationController.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -276,7 +276,7 @@
// return;
}
- Vector2 coord = get2DViewcoordinates(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
+ Vector2 coord = get2DViewCoordinates(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
float distance = (target - this->getControllableEntity()->getPosition()).length();
float rotateX = clamp(coord.x * 10, -1.0f, 1.0f);
float rotateY = clamp(coord.y * 10, -1.0f, 1.0f);
@@ -969,6 +969,8 @@
controller = entity1->getXMLController();
if (controller)
{
+ if (controller->getIdentifier()->getName() == "MasterController")
+ return true;
FormationController* ac = orxonox_cast<FormationController*>(controller);
if (ac)
team1 = ac->getTeam();
@@ -980,6 +982,8 @@
controller = entity2->getXMLController();
if (controller)
{
+ if (controller->getIdentifier()->getName() == "MasterController")
+ return true;
FormationController* ac = orxonox_cast<FormationController*>(controller);
if (ac)
team2 = ac->getTeam();
@@ -1068,7 +1072,7 @@
if (!this->getControllableEntity())
return;
- Vector2 coord = get2DViewcoordinates(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
+ Vector2 coord = get2DViewCoordinates(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
float distance = (target - this->getControllableEntity()->getPosition()).length();
if (this->target_ || distance > minDistance)
Copied: code/branches/presentationHS15/src/orxonox/controllers/MasterController.cc (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/MasterController.cc)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/MasterController.cc (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/MasterController.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,131 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#include "MasterController.h"
+#include "controllers/ActionpointController.h"
+namespace orxonox
+{
+
+ RegisterClass(MasterController);
+
+ //Leaders share the fact that they have Wingmans
+ MasterController::MasterController(Context* context) : Controller(context)
+ {
+ RegisterObject(MasterController);
+ // orxout(internal_error) << "MasterController was created" << endl;
+
+ this->controllers_.clear();
+ this->numberOfTicksPassedSinceLastActionCall_ = 0;
+ this->indexOfCurrentController_ = 0;
+ this->ticks_ = 0;
+ }
+
+ MasterController::~MasterController()
+ {
+ this->controllers_.clear();
+ }
+ void MasterController::tick(float dt)
+ {
+ if (!this->isActive())
+ return;
+ ++this->ticks_;
+ //orxout(internal_error) << "Tick = " << this->ticks_ << endl;
+ if (this->ticks_ == 1)
+ {
+ //fill the vector in the first tick
+ for (ObjectList<ActionpointController>::iterator it = ObjectList<ActionpointController>::begin(); it; ++it)
+ {
+ //----0ptr?----
+ if (!it)
+ continue;
+ this->controllers_.push_back(*it);
+ }
+ //orxout(internal_error) << "I got " << this->controllers_.size() << " controllers" << endl;
+ }
+ else
+ {
+
+ if (this->controllers_.empty())
+ return;
+
+ //iterate over vecotr with the index, keep index in boundaries
+ if (this->indexOfCurrentController_ >= this->controllers_.size())
+ {
+ this->indexOfCurrentController_ = 0;
+ }
+ //each 9 ticks index is incremented
+ if (this->numberOfTicksPassedSinceLastActionCall_ >= 9)
+ {
+ this->numberOfTicksPassedSinceLastActionCall_ = 0;
+ }
+
+ if (this->numberOfTicksPassedSinceLastActionCall_ > 0)
+ {
+ //call maneuver for current index
+ if (this->numberOfTicksPassedSinceLastActionCall_ == 3)
+ {
+ if (!this->controllers_.at(this->indexOfCurrentController_))
+ {
+ this->controllers_.erase(this->controllers_.begin() + this->indexOfCurrentController_);
+ return;
+ }
+ //orxout (internal_error) << "Executing maneuver of Controller # " << this->indexOfCurrentController_ << endl;
+ this->controllers_.at(this->indexOfCurrentController_)->maneuver();
+ }
+ else if (this->numberOfTicksPassedSinceLastActionCall_ == 6)
+ {
+ //call canFire for current index
+ if (!this->controllers_.at(this->indexOfCurrentController_))
+ {
+ this->controllers_.erase(this->controllers_.begin() + this->indexOfCurrentController_);
+ return;
+ }
+ //orxout (internal_error) << "Executing maneuver of Controller # " << this->indexOfCurrentController_ << endl;
+ this->controllers_.at(this->indexOfCurrentController_)->bShooting_ = this->controllers_.at(this->indexOfCurrentController_)->canFire();
+ }
+ ++this->numberOfTicksPassedSinceLastActionCall_;
+ }
+ else
+ {
+ //call action for current index
+ if (!this->controllers_.at(this->indexOfCurrentController_))
+ {
+ this->controllers_.erase(this->controllers_.begin() + this->indexOfCurrentController_);
+ return;
+ }
+ //orxout (internal_error) << "Executing action of Controller # " << this->indexOfCurrentController_ << endl;
+ this->controllers_.at(this->indexOfCurrentController_)->action();
+ //bCopyOrientation makes ship oscillate like crazy if set to true all the time.s
+ this->controllers_.at(this->indexOfCurrentController_)->bCopyOrientation_ = this->ticks_ % 3 == 0;
+
+ ++this->numberOfTicksPassedSinceLastActionCall_;
+ ++this->indexOfCurrentController_;
+ }
+ }
+ }
+}
Copied: code/branches/presentationHS15/src/orxonox/controllers/MasterController.h (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/MasterController.h)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/MasterController.h (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/MasterController.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,78 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#ifndef _MasterController_H__
+#define _MasterController_H__
+
+#include "controllers/Controller.h"
+#include "controllers/ActionpointController.h"
+#include "tools/interfaces/Tickable.h"
+
+
+
+namespace orxonox
+{
+ /**
+ @brief
+ calles action(), maneuver() and canFire() methods of all the ActionpointControllers in level.
+ Only one instance of MasterController is to be placed in level.
+ If no MasterController is initialized, none of ActionpointControllers will work.
+ Example:
+ <Pawn position = "100000, 100000, 100000">
+ <controller>
+ <MasterController>
+ </MasterController>
+ </controller>
+ </Pawn>
+ */
+ class _OrxonoxExport MasterController : public Controller, public Tickable
+ {
+ public:
+ //----[language demanded functions]----
+ MasterController(Context* context);
+
+ virtual ~MasterController();
+ //----[/language demanded functions]----
+
+ //----[orxonox demanded functions]----
+ virtual void tick(float dt);
+
+ //----[orxonox demanded functions]----
+
+ protected:
+
+ private:
+ std::vector<WeakPtr<ActionpointController> > controllers_; //<! vector of controllers, which action(), canFire() and maneuver() methods are to be called
+ size_t indexOfCurrentController_; //<! index of current controller
+ unsigned int numberOfTicksPassedSinceLastActionCall_;
+ unsigned int ticks_; //<! local tick counter
+
+ };
+}
+
+#endif /* _MasterController_H__ */
Copied: code/branches/presentationHS15/src/orxonox/controllers/SectionController.cc (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/SectionController.cc)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/SectionController.cc (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/SectionController.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,290 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#include "SectionController.h"
+
+namespace orxonox
+{
+
+ RegisterClass(SectionController);
+
+ //Leaders share the fact that they have Wingmans
+ SectionController::SectionController(Context* context) : ActionpointController(context)
+ {
+ RegisterObject(SectionController);
+ this->setFormationMode(FormationMode::FINGER4);
+
+ this->myWingman_ = 0;
+ this->myDivisionLeader_ = 0;
+ this->bFirstAction_ = true;
+
+ }
+
+ SectionController::~SectionController()
+ {
+ for (size_t i = 0; i < this->actionpoints_.size(); ++i)
+ {
+ if(this->actionpoints_[i])
+ this->actionpoints_[i]->destroy();
+ }
+ this->parsedActionpoints_.clear();
+ this->actionpoints_.clear();
+ }
+ void SectionController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+ {
+ SUPER(SectionController, XMLPort, xmlelement, mode);
+ }
+
+ //----in tick, move (or look) and shoot----
+ void SectionController::tick(float dt)
+ {
+ if (!this->isActive())
+ return;
+
+ SUPER(SectionController, tick, dt);
+
+ }
+
+ void SectionController::action()
+ {
+ if (!this || !this->getControllableEntity() || !this->isActive())
+ return;
+
+ //----If no leader, find one----
+ if (!myDivisionLeader_)
+ {
+ ActionpointController* newDivisionLeader = findNewDivisionLeader();
+ if (!this || !this->getControllableEntity())
+ return;
+
+ this->myDivisionLeader_ = newDivisionLeader;
+ //spread copyOrientation called equally among the division
+
+ }
+ //----If have leader----
+ else
+ {
+ }
+ if (!myDivisionLeader_)
+ {
+ ActionpointController::action();
+ if (!this || !this->getControllableEntity())
+ return;
+ if (!(this->parsedActionpoints_.empty() && this->loopActionpoints_.empty()))
+ {
+ if (this->myWingman_)
+ {
+ this->myWingman_->takeActionpoints(this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+ }
+ }
+ }
+ else if (myDivisionLeader_)
+ {
+ if (this->myDivisionLeader_->bKeepFormation_ || !(this->myDivisionLeader_->getAction() == Action::FIGHT
+ || this->myDivisionLeader_->getAction() == Action::FIGHTALL
+ || this->myDivisionLeader_->getAction() == Action::ATTACK))
+ {
+ this->keepFormation();
+ //orxout (internal_error) << "Keeping formation" << endl;
+
+ }
+ else if (!this->myDivisionLeader_->bKeepFormation_)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+
+ if (!this->hasTarget())
+ {
+ this->chooseTarget();
+ }
+
+ }
+ }
+
+ }
+
+
+ //PRE: myDivisionLeader_ != 0 && myDivisionLeader_->action_ == Action::FIGHT
+ //POST: this->target_ is set unless division leader doesn't have one
+ void SectionController::chooseTarget()
+ {
+ //----If division leader fights, cover him by fighting emenies close to his target----
+ Action::Value action = this->myDivisionLeader_->getAction();
+
+ if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
+ {
+ Pawn* target;
+ //----if he has a target----
+ if (this->myDivisionLeader_->hasTarget())
+ {
+ //----try to find a new target if division leader has wingman (doing fine) and no good target already set----
+ if ( this->myDivisionLeader_->hasWingman() &&
+ !( this->hasTarget() && this->getTarget() != this->myDivisionLeader_->getTarget() ) )
+ {
+ bool foundTarget = false;
+ //----new target should be close to division's target----
+ Vector3 divisionTargetPosition = this->myDivisionLeader_->getTarget()->getWorldPosition();
+ Gametype* gt = this->getGametype();
+ for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
+ {
+ //----is enemy?----
+ if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
+ continue;
+ //----in range?----
+ if (((*itP)->getWorldPosition() - divisionTargetPosition).length() < 3000 &&
+ (*itP) != this->myDivisionLeader_->getTarget())
+ {
+ foundTarget = true;
+ target = (*itP);
+ //orxout(internal_error) << "Found target" << endl;
+ break;
+ }
+ }
+ //----no target? then attack same target as division leader----
+ if (!foundTarget)
+ {
+ target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
+ }
+ }
+ //----if division leader doesn't have a wingman, support his fire----
+ else
+ {
+ target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
+ }
+ }
+ //----If he fights but doesn't have a target, wait for him to get one----
+ else
+ {
+
+ }
+ this->setTarget (orxonox_cast<ControllableEntity*>(target));
+ }
+ else
+ {
+ }
+ }
+ Vector3 SectionController::getFormationPosition ()
+ {
+ this->setFormationMode( this->myDivisionLeader_->getFormationMode() );
+ this->spread_ = this->myDivisionLeader_->getSpread();
+ Vector3* targetRelativePosition;
+ switch (this->formationMode_){
+ case FormationMode::WALL:
+ {
+ targetRelativePosition = new Vector3 (-2*this->spread_, 0, 0);
+ break;
+ }
+ case FormationMode::FINGER4:
+ {
+ targetRelativePosition = new Vector3 (-2*this->spread_, 0, this->spread_);
+ break;
+ }
+
+ case FormationMode::DIAMOND:
+ {
+ targetRelativePosition = new Vector3 (-2*this->spread_, 0, this->spread_);
+ break;
+ }
+ }
+ Vector3 result = *targetRelativePosition;
+ delete targetRelativePosition;
+ return result;
+ }
+
+ void SectionController::keepFormation()
+ {
+ this->bKeepFormation_ = true;
+ ControllableEntity* leaderEntity = this->myDivisionLeader_->getControllableEntity();
+ Vector3 targetRelativePosition = this->getFormationPosition();
+ if (!leaderEntity)
+ return;
+ FlyingController::keepFormation(leaderEntity, targetRelativePosition);
+ }
+
+ ActionpointController* SectionController::findNewDivisionLeader()
+ {
+
+ if (!this->getControllableEntity())
+ return 0;
+
+ ActionpointController* closestLeader = 0;
+ float minDistance = std::numeric_limits<float>::infinity();
+ //go through all pawns
+ for (ObjectList<ActionpointController>::iterator it = ObjectList<ActionpointController>::begin(); it; ++it)
+ {
+ //0ptr or not DivisionController?
+ if (!(it) || !((it)->getIdentifier()->getName() == "DivisionController") || !(it->getControllableEntity()))
+ continue;
+ //same team?
+ if ((this->getControllableEntity()->getTeam() != (it)->getControllableEntity()->getTeam()))
+ continue;
+
+ //is equal to this?
+ if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity())
+ continue;
+
+ float distance = CommonController::distance (it->getControllableEntity(), this->getControllableEntity());
+
+ if (distance < minDistance && !(it->hasFollower()))
+ {
+ closestLeader = *it;
+ minDistance = distance;
+ }
+
+ }
+ if (closestLeader)
+ {
+ if (closestLeader->setFollower(this))
+ return closestLeader;
+ }
+ return 0;
+ }
+
+ bool SectionController::setWingman(ActionpointController* newWingman)
+ {
+
+ if (!this->myWingman_)
+ {
+ this->myWingman_ = newWingman;
+ newWingman->takeActionpoints (this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ bool SectionController::hasWingman()
+ {
+ if (this->myWingman_)
+ return true;
+ else
+ return false;
+ }
+}
Copied: code/branches/presentationHS15/src/orxonox/controllers/SectionController.h (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/SectionController.h)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/SectionController.h (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/SectionController.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,78 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#ifndef _SectionController_H__
+#define _SectionController_H__
+
+#include "controllers/ActionpointController.h"
+
+
+namespace orxonox
+{
+ /**
+ @note
+ ActionpointController will not work, if there is no MasterController in the level!
+ */
+ class _OrxonoxExport SectionController : public ActionpointController
+ {
+ public:
+ //----[language demanded functions]----
+ SectionController(Context* context);
+
+ virtual ~SectionController();
+ //----[/language demanded functions]----
+
+ //----[orxonox demanded functions]----
+ virtual void tick(float dt);
+
+ virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+ //----[/orxonox demanded functions]----
+
+ //----[own functions]----
+ ActionpointController* findNewDivisionLeader();
+
+ virtual bool setWingman(ActionpointController* newWingman);
+ virtual bool hasWingman();
+ virtual bool hasFollower()
+ { return false; }
+ void chooseTarget();
+ //----[/own functions]----
+
+ protected:
+ //----action must only be managed by this----
+ virtual void action(); //<! action() is called in regular intervals managing the bot's behaviour.
+ Vector3 getFormationPosition ();
+ void keepFormation();
+ private:
+ //----private variables-----
+ bool bFirstAction_;
+
+ };
+}
+
+#endif /* _SectionController_H__ */
Copied: code/branches/presentationHS15/src/orxonox/controllers/WingmanController.cc (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/WingmanController.cc)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/WingmanController.cc (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/WingmanController.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,233 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#include "WingmanController.h"
+
+
+namespace orxonox
+{
+
+ RegisterClass(WingmanController);
+
+ //ActionpointController contains all common functionality of AI Controllers
+ WingmanController::WingmanController(Context* context) : ActionpointController(context)
+ {
+ RegisterObject(WingmanController);
+ this->myLeader_ = 0;
+ this->bFirstAction_ = true;
+
+ }
+
+ WingmanController::~WingmanController()
+ {
+ for (size_t i = 0; i < this->actionpoints_.size(); ++i)
+ {
+ if(this->actionpoints_[i])
+ this->actionpoints_[i]->destroy();
+ }
+ this->parsedActionpoints_.clear();
+ this->actionpoints_.clear();
+ }
+
+ void WingmanController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+ {
+ SUPER(WingmanController, XMLPort, xmlelement, mode);
+ }
+
+ //----in tick, move (or look) and shoot----
+ void WingmanController::tick(float dt)
+ {
+ if (!this->isActive())
+ return;
+
+ SUPER(WingmanController, tick, dt);
+
+ }
+
+ //----action for hard calculations----
+ void WingmanController::action()
+ {
+ if (!this || !this->getControllableEntity() || !this->isActive())
+ return;
+ //----If no leader, find one----
+ if (!this->myLeader_)
+ {
+ ActionpointController* newLeader = (findNewLeader());
+ if (!this || !this->getControllableEntity())
+ return;
+
+ this->myLeader_ = newLeader;
+ if (this->myLeader_)
+ {
+
+ }
+ }
+ //----If have leader, he will deal with logic----
+ else
+ {
+
+ }
+ if (!this->myLeader_)
+ {
+ ActionpointController::action();
+ }
+ else if (this->myLeader_)
+ {
+ if (this->myLeader_->bKeepFormation_ || !(this->myLeader_->getAction() == Action::FIGHT || this->myLeader_->getAction() == Action::FIGHTALL
+ || this->myLeader_->getAction() == Action::ATTACK))
+ {
+ this->keepFormation();
+ }
+ else if (!this->myLeader_->bKeepFormation_)
+ {
+ if (!this || !this->getControllableEntity())
+ return;
+
+ if (!this->hasTarget())
+ {
+ this->setTarget(this->myLeader_->getTarget());
+ }
+
+ }
+ }
+ }
+
+
+ Vector3 WingmanController::getFormationPosition ()
+ {
+
+
+ this->setFormationMode( this->myLeader_->getFormationMode() );
+ Vector3* targetRelativePosition;
+ this->spread_ = this->myLeader_->getSpread();
+ if (this->myLeader_->getIdentifier()->getName() == "DivisionController")
+ {
+ switch (this->formationMode_){
+ case FormationMode::WALL:
+ {
+ targetRelativePosition = new Vector3 (2*this->spread_, 0, 0 - this->tolerance_);
+ break;
+ }
+ case FormationMode::FINGER4:
+ {
+ targetRelativePosition = new Vector3 (2*this->spread_, 0, this->spread_ - this->tolerance_);
+ break;
+ }
+ case FormationMode::DIAMOND:
+ {
+ targetRelativePosition = new Vector3 (2*this->spread_, 0, this->spread_ - this->tolerance_);
+ break;
+ }
+ }
+ }
+ else
+ {
+
+ switch (this->formationMode_){
+ case FormationMode::WALL:
+ {
+ targetRelativePosition = new Vector3 (-2*this->spread_, 0, 0 - this->tolerance_);
+ break;
+ }
+ case FormationMode::FINGER4:
+ {
+ targetRelativePosition = new Vector3 (-2*this->spread_, 0, this->spread_ - this->tolerance_);
+ break;
+ }
+ case FormationMode::DIAMOND:
+ {
+ targetRelativePosition = new Vector3 (2*this->spread_, -this->spread_, 0 - this->tolerance_);
+ break;
+ }
+ }
+ }
+ Vector3 result = *targetRelativePosition;
+ delete targetRelativePosition;
+ return result;
+ }
+ void WingmanController::keepFormation()
+ {
+ this->bKeepFormation_ = true;
+ ControllableEntity* leaderEntity = this->myLeader_->getControllableEntity();
+ Vector3 targetRelativePosition = this->getFormationPosition();
+ if (!leaderEntity)
+ return;
+ FlyingController::keepFormation (leaderEntity, targetRelativePosition);
+ }
+ //----POST: closest leader that is ready to take a new wingman is returned----
+ ActionpointController* WingmanController::findNewLeader()
+ {
+
+ if (!this->getControllableEntity())
+ return 0;
+
+ //----vars for finding the closest leader----
+ ActionpointController* closestLeader = 0;
+ float minDistance = std::numeric_limits<float>::infinity();
+ Gametype* gt = this->getGametype();
+
+ for (ObjectList<ActionpointController>::iterator it = ObjectList<ActionpointController>::begin(); it; ++it)
+ {
+ //----0ptr or not a leader or dead?----
+ if (!it ||
+ (it->getIdentifier()->getName() != "SectionController" && it->getIdentifier()->getName() != "DivisionController") ||
+ !(it->getControllableEntity()))
+ continue;
+
+ //----same team?----
+ if ( !CommonController::sameTeam (this->getControllableEntity(), (it)->getControllableEntity(), gt) )
+ continue;
+
+ //----check distance----
+ float distance = CommonController::distance (it->getControllableEntity(), this->getControllableEntity());
+ if (distance < minDistance && !(it->hasWingman()))
+ {
+ closestLeader = *it;
+ minDistance = distance;
+ }
+ }
+ if (closestLeader)
+ {
+ //----Racing conditions----
+ if (closestLeader->setWingman(orxonox_cast<ActionpointController*>(this)))
+ {
+ if (closestLeader->getIdentifier()->getName() == "SectionController")
+ {
+ this->actionTime_ = 1.6f;
+ }
+ else
+ {
+ this->actionTime_ = 2.0f;
+ }
+ return closestLeader;
+ }
+ }
+ return 0;
+ }
+
+}
Copied: code/branches/presentationHS15/src/orxonox/controllers/WingmanController.h (from rev 10967, code/branches/campaignHS15/src/orxonox/controllers/WingmanController.h)
===================================================================
--- code/branches/presentationHS15/src/orxonox/controllers/WingmanController.h (rev 0)
+++ code/branches/presentationHS15/src/orxonox/controllers/WingmanController.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,81 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#ifndef _WingmanController_H__
+#define _WingmanController_H__
+
+
+#include "controllers/ActionpointController.h"
+
+
+namespace orxonox
+{
+ /**
+ @note
+ ActionpointController will not work, if there is no MasterController in the level!
+ */
+ class _OrxonoxExport WingmanController : public ActionpointController
+ {
+ public:
+ //----[language demanded functions]----
+ WingmanController(Context* context);
+
+ virtual ~WingmanController();
+ //----[/language demanded functions]----
+
+ //----[orxonox demanded functions]----
+ virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+ virtual void tick(float dt);
+ virtual bool hasWingman()
+ { return false; }
+ virtual bool hasFollower()
+ { return false; }
+ //----[/orxonox demanded functions]----
+
+ //----[own functions]----
+ ActionpointController* findNewLeader();
+ //----[/own functions]----
+
+ protected:
+ //----action must only be managed by this----
+ virtual void action(); //<! action() is called in regular intervals managing the bot's behaviour.
+ Vector3 getFormationPosition ();
+ void keepFormation();
+
+ private:
+ //----private variables-----
+ WeakPtr<ActionpointController> myLeader_;
+ bool bFirstAction_;
+ float actionTime_;
+
+
+ };
+}
+
+#endif /* _WingmanController_H__ */
Copied: code/branches/presentationHS15/src/orxonox/worldentities/Actionpoint.cc (from rev 10967, code/branches/campaignHS15/src/orxonox/worldentities/Actionpoint.cc)
===================================================================
--- code/branches/presentationHS15/src/orxonox/worldentities/Actionpoint.cc (rev 0)
+++ code/branches/presentationHS15/src/orxonox/worldentities/Actionpoint.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,85 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#include "Actionpoint.h"
+
+namespace orxonox
+{
+ RegisterClass(Actionpoint);
+
+ Actionpoint::Actionpoint(Context* context) : StaticEntity(context)
+ {
+ RegisterObject(Actionpoint);
+
+ this->actionName_ = "";
+ this->name_ = "";
+
+ this->bLoopStart_ = false;
+ this->bLoopEnd_ = false;
+ this->bProtectMe_ = false;
+ }
+
+ void Actionpoint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+ {
+ SUPER(Actionpoint, XMLPort, xmlelement, mode);
+
+ XMLPortParam(Actionpoint, "action", setActionXML, getActionXML, xmlelement, mode);
+ XMLPortParam(Actionpoint, "protect", setProtectXML, getProtectXML, xmlelement, mode);
+ XMLPortParam(Actionpoint, "attack", setAttackXML, getAttackXML, xmlelement, mode);
+ XMLPortParam(Actionpoint, "protectMe", setProtectMeXML, getProtectMeXML, xmlelement, mode).defaultValues(false);
+ XMLPortParam(Actionpoint, "loopStart", setLoopStart, getLoopStart, xmlelement, mode).defaultValues(false);
+ XMLPortParam(Actionpoint, "loopEnd", setLoopEnd, getLoopEnd, xmlelement, mode).defaultValues(false);
+ }
+ /**
+ @brief
+ action is ATTACK -> returns name of object to attack
+ action is PROTECT -> returns name of object to protect
+ if asked to protect human, returns a special string.
+ @return
+ name of an object to interact with.
+ @note
+ never use more than one of following arguments for XMLPort:
+ attack, protect, protectMe or
+ loopStart and loopEnd.
+ */
+ std::string Actionpoint::getName() const
+ {
+ if (this->name_ != "")
+ {
+ return this->name_;
+ }
+ else if (this->bProtectMe_)
+ {
+ return "reservedKeyword:human";
+ }
+ else
+ {
+ return "";
+ }
+ }
+}
Copied: code/branches/presentationHS15/src/orxonox/worldentities/Actionpoint.h (from rev 10967, code/branches/campaignHS15/src/orxonox/worldentities/Actionpoint.h)
===================================================================
--- code/branches/presentationHS15/src/orxonox/worldentities/Actionpoint.h (rev 0)
+++ code/branches/presentationHS15/src/orxonox/worldentities/Actionpoint.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -0,0 +1,156 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Gani Aliguzhinov
+ * Co-authors:
+ * ...
+ *
+ */
+
+#ifndef _Actionpoint_H__
+#define _Actionpoint_H__
+
+#include <string> //need string for XML input
+
+#include "core/XMLPort.h" //need XMLPort
+#include "worldentities/StaticEntity.h" //this is a child of StaticEntity
+
+namespace orxonox
+{
+ /**
+ @brief
+ Actionpoints are used by ActionpointController and all derived classes.
+ Such classes will execute actions set in Actionpoints.
+
+ In XML file one can pass an array of Actionpoints to a controller. Each
+ Actionpoint can take action type, string and boolean or
+ action and two booleans as an argument.
+ If action is set to fly, Actionpoint's position is assumed to be the desired
+ location.
+ Example XML code:
+
+ <SpaceShip position="-2000, 1500, -1000" lookat="0,0,0" team=0 name="thisShipName">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=0 formationMode="WALL">
+ <actionpoints>
+ <Actionpoint position="0,0,0" action="FLY" />
+ <Actionpoint position="-1000,750,-500" action="ATTACK" attack="someShipName" />
+ <Actionpoint position="-1000,750,-500" action="PROTECT" protectMe=true />
+ <Actionpoint position="-1000,750,-500" action="PROTECT" protect="otherShipName" />
+ <Actionpoint position="-1000,750,-500" action="FIGHTALL" />
+ </actionpoints>
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+
+ Example with loops:
+
+ <SpaceShip position="-1500, 1500, -1000" lookat="0,0,0" team=0 name="thisShipName">
+ <templates>
+ <Template link=spaceshipassff />
+ </templates>
+ <controller>
+ <DivisionController team=0 formationMode="finger4">
+ <actionpoints>
+ <Actionpoint position=" 0,2000,-600" action="FLY" loopStart=true/>
+ <Actionpoint position=" 0,2000,-700" action="FLY" />
+ <Actionpoint position="100,2000,-700" action="FLY" />
+ <Actionpoint position="100,2000,-600" action="FLY" loopEnd=true />
+ </actionpoints>
+ </DivisionController>
+ </controller>
+ </SpaceShip>
+
+ One can also use other Worldentities instead of Actionpoints just like Waypoints, but those points
+ will be included in loop.
+ For more information read descriptions of the methods.
+ */
+ class _OrxonoxExport Actionpoint : public StaticEntity
+ {
+ public:
+ Actionpoint(Context* context);
+ virtual ~Actionpoint() {}
+
+ virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+ /** @brief Decides what AI will do. @param val action to execute */
+ void setActionXML(std::string val)
+ { this->actionName_ = getUppercase (val); }
+ std::string getActionXML() const
+ { return this->actionName_; }
+
+ /** @brief Makes AI follow an entity. @param val name of entity to protect */
+ void setProtectXML(std::string val)
+ { this->name_ = val; }
+ std::string getProtectXML() const
+ { return this->name_; }
+
+ /** @brief Makes AI attack an entity. @param val name of entity to attack */
+ void setAttackXML(std::string val)
+ { this->name_ = val; }
+ std::string getAttackXML() const
+ { return this->name_; }
+
+ /** @brief Makes AI follow human player. @param c protect Human? */
+ void setProtectMeXML(bool c)
+ { this->bProtectMe_ = c; }
+ bool getProtectMeXML() const
+ { return this->bProtectMe_; }
+
+ /** @brief Starts a loop of Actionpoints. @param value start loop? */
+ void setLoopStart(bool value)
+ { this->bLoopStart_ = value; }
+ bool getLoopStart() const
+ { return this->bLoopStart_; }
+ /** @brief Ends a loop of Actionpoints. @param value end loop? */
+ void setLoopEnd (bool value)
+ { this->bLoopEnd_ = value; }
+ bool getLoopEnd() const
+ { return this->bLoopEnd_; }
+
+ std::string getName() const;
+
+ private:
+ std::string actionName_; //!< can be set to "FLY", "ATTACK",
+ //!< "PROTECT", "FIGHT", "FIGHTALL"
+ //!< or "NONE".
+
+ std::string name_; //!< name of the ship that is to be
+ //!< attacked or protected.
+
+ bool bLoopStart_; //!< if true, this and all following Actionpoints
+ //!< until the first Actionpoint with bLoopEnd_
+ //!< set to true are executed in a loop.
+
+ bool bLoopEnd_; //!< if true, this is the last element of
+ //!< a loop started by loopStart=true argument
+
+ bool bProtectMe_; //!< if player is to be protected,
+ //!< instead of passing name, one has
+ //!< to set protectMe to true.
+ };
+}
+
+#endif /* _Actionpoint_H__ */
Modified: code/branches/presentationHS15/src/orxonox/worldentities/CMakeLists.txt
===================================================================
--- code/branches/presentationHS15/src/orxonox/worldentities/CMakeLists.txt 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/orxonox/worldentities/CMakeLists.txt 2015-12-11 14:26:20 UTC (rev 10970)
@@ -11,6 +11,7 @@
SpawnPoint.cc
TeamSpawnPoint.cc
ExplosionPart.cc
+ Actionpoint.cc
)
ADD_SUBDIRECTORY(pawns)
Modified: code/branches/presentationHS15/src/orxonox/worldentities/SpawnPoint.h
===================================================================
--- code/branches/presentationHS15/src/orxonox/worldentities/SpawnPoint.h 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/orxonox/worldentities/SpawnPoint.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -54,7 +54,7 @@
inline Template* getTemplate() const
{ return this->template_; }
- Pawn* spawn();
+ virtual Pawn* spawn();
void spawn(ControllableEntity* entity);
private:
Modified: code/branches/presentationHS15/src/orxonox/worldentities/TeamSpawnPoint.cc
===================================================================
--- code/branches/presentationHS15/src/orxonox/worldentities/TeamSpawnPoint.cc 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/orxonox/worldentities/TeamSpawnPoint.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -48,4 +48,10 @@
XMLPortParam(TeamSpawnPoint, "team", setTeamNumber, getTeamNumber, xmlelement, mode).defaultValues(0);
}
+ Pawn* TeamSpawnPoint::spawn()
+ {
+ Pawn* entity = SpawnPoint::spawn();
+ static_cast<ControllableEntity*>(entity)->setTeam (this->teamNumber_);
+ return entity;
+ }
}
Modified: code/branches/presentationHS15/src/orxonox/worldentities/TeamSpawnPoint.h
===================================================================
--- code/branches/presentationHS15/src/orxonox/worldentities/TeamSpawnPoint.h 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/orxonox/worldentities/TeamSpawnPoint.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -48,9 +48,10 @@
{ this->teamNumber_ = team; }
unsigned int getTeamNumber() const
{ return this->teamNumber_; }
+ virtual Pawn* spawn();
private:
- unsigned int teamNumber_;
+ int teamNumber_;
};
}
Modified: code/branches/presentationHS15/src/orxonox/worldentities/pawns/Pawn.h
===================================================================
--- code/branches/presentationHS15/src/orxonox/worldentities/pawns/Pawn.h 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/src/orxonox/worldentities/pawns/Pawn.h 2015-12-11 14:26:20 UTC (rev 10970)
@@ -200,6 +200,9 @@
void setExplosionSound(const std::string& engineSound);
const std::string& getExplosionSound();
+ virtual const WeaponSystem* getWeaponSystem() const
+ { return this->weaponSystem_; }
+
protected:
virtual void preDestroy();
Modified: code/branches/presentationHS15/test/util/MathTest.cc
===================================================================
--- code/branches/presentationHS15/test/util/MathTest.cc 2015-12-11 14:20:17 UTC (rev 10969)
+++ code/branches/presentationHS15/test/util/MathTest.cc 2015-12-11 14:26:20 UTC (rev 10970)
@@ -336,7 +336,7 @@
/*
getAngle
get2DViewdirection
- get2DViewcoordinates
+ get2DViewCoordinates
getPredictedPosition
*/
}
More information about the Orxonox-commit
mailing list