Added startup scripts
This commit is contained in:
parent
a479fa4ac1
commit
13ef92160d
@ -174,6 +174,7 @@ set(EMSCRIPTEN_LINK_FLAGS
|
||||
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/shaders@resources/shaders"
|
||||
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/start.lua@resources/start.lua"
|
||||
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/start2.lua@resources/start2.lua"
|
||||
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/start_dorm.lua@resources/start_dorm.lua"
|
||||
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../audio@audio"
|
||||
)
|
||||
|
||||
|
||||
@ -51,6 +51,87 @@
|
||||
"positionZ": 0.0,
|
||||
"scale": 1.0,
|
||||
"interactive": false
|
||||
},
|
||||
{
|
||||
"name": "Bed001",
|
||||
"texturePath": "resources/w/dorm/ikea_bed_bake002.png",
|
||||
"meshPath": "resources/w/dorm/ikea_bed001.txt",
|
||||
"rotationX": 0.0,
|
||||
"rotationY": 0.0,
|
||||
"rotationZ": 0.0,
|
||||
"positionX": 0.0,
|
||||
"positionY": -0.1,
|
||||
"positionZ": 0.0,
|
||||
"scale": 1.0,
|
||||
"interactive": false
|
||||
},
|
||||
{
|
||||
"name": "Chair001",
|
||||
"texturePath": "resources/w/dorm/ikea_chair_bake002.png",
|
||||
"meshPath": "resources/w/dorm/ikea_chair001.txt",
|
||||
"rotationX": 0.0,
|
||||
"rotationY": 0.0,
|
||||
"rotationZ": 0.0,
|
||||
"positionX": 0.0,
|
||||
"positionY": -0.1,
|
||||
"positionZ": 0.0,
|
||||
"scale": 1.0,
|
||||
"interactive": false
|
||||
},
|
||||
{
|
||||
"name": "Table001",
|
||||
"texturePath": "resources/w/dorm/ikea_table_bake003.png",
|
||||
"meshPath": "resources/w/dorm/ikea_table001.txt",
|
||||
"rotationX": 0.0,
|
||||
"rotationY": 0.0,
|
||||
"rotationZ": 0.0,
|
||||
"positionX": 0.0,
|
||||
"positionY": -0.1,
|
||||
"positionZ": 0.0,
|
||||
"scale": 1.0,
|
||||
"interactive": false
|
||||
},
|
||||
{
|
||||
"name": "Phone001",
|
||||
"texturePath": "resources/w/dorm/phone001_tex001.png",
|
||||
"meshPath": "resources/w/dorm/phone001.txt",
|
||||
"rotationX": 0.0,
|
||||
"rotationY": 0.0,
|
||||
"rotationZ": 0.0,
|
||||
"positionX": 5.8729,
|
||||
"positionY": 1.04917,
|
||||
"positionZ": -12.5262,
|
||||
"scale": 1.0,
|
||||
"interactive": true,
|
||||
"item": {
|
||||
"id": "phone",
|
||||
"name": "Телефон",
|
||||
"description": "Я не могу себе представить жизнь без своего телефона",
|
||||
"icon": "resources/fire2.png",
|
||||
"radius": 0.3
|
||||
},
|
||||
"activateFunction" : "on_phone_pickup"
|
||||
},
|
||||
{
|
||||
"name": "Journal001",
|
||||
"texturePath": "resources/w/dorm/journal001_tex002.png",
|
||||
"meshPath": "resources/w/dorm/journal001.txt",
|
||||
"rotationX": 0.0,
|
||||
"rotationY": 0.0,
|
||||
"rotationZ": 0.0,
|
||||
"positionX": 5.05146,
|
||||
"positionY": 1.06711,
|
||||
"positionZ": -12.4661,
|
||||
"scale": 1.0,
|
||||
"interactive": true,
|
||||
"item": {
|
||||
"id": "journal",
|
||||
"name": "Телефон",
|
||||
"description": "Это мой журнал куда я вношу свои заметки.",
|
||||
"icon": "resources/fire2.png",
|
||||
"radius": 0.3
|
||||
},
|
||||
"activateFunction" : "on_journal_pickup"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -28,25 +28,26 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"obstacles": [
|
||||
"obstacles": [
|
||||
|
||||
{
|
||||
"name": "editor_obstacle_1",
|
||||
"polygon": [
|
||||
[
|
||||
1.4521160125732422,
|
||||
-15.647087097167969
|
||||
1.2386366128921509,
|
||||
-16.910831451416016
|
||||
],
|
||||
[
|
||||
0.7836513519287109,
|
||||
-15.604467391967773
|
||||
1.2082710266113281,
|
||||
-15.74820327758789
|
||||
],
|
||||
[
|
||||
0.8457736968994141,
|
||||
-17.430662155151367
|
||||
0.9836082458496094,
|
||||
-15.767669677734375
|
||||
],
|
||||
[
|
||||
1.3778166770935059,
|
||||
-17.40001678466797
|
||||
0.9937065839767456,
|
||||
-16.89757537841797
|
||||
]
|
||||
]
|
||||
},
|
||||
@ -54,20 +55,20 @@
|
||||
"name": "editor_obstacle_2",
|
||||
"polygon": [
|
||||
[
|
||||
1.238701343536377,
|
||||
-17.41904640197754
|
||||
1.2371597290039063,
|
||||
-14.667628288269043
|
||||
],
|
||||
[
|
||||
1.2542033195495605,
|
||||
-16.888349533081055
|
||||
1.0021405220031738,
|
||||
-14.565974235534668
|
||||
],
|
||||
[
|
||||
8.557634353637695,
|
||||
-16.686010360717773
|
||||
0.8893742561340332,
|
||||
-11.02865982055664
|
||||
],
|
||||
[
|
||||
8.580190658569336,
|
||||
-17.49493980407715
|
||||
1.2916733026504517,
|
||||
-11.256534576416016
|
||||
]
|
||||
]
|
||||
},
|
||||
@ -75,20 +76,20 @@
|
||||
"name": "editor_obstacle_3",
|
||||
"polygon": [
|
||||
[
|
||||
8.581539154052734,
|
||||
-17.44879150390625
|
||||
1.15517258644104,
|
||||
-16.825780868530273
|
||||
],
|
||||
[
|
||||
9.2276029586792,
|
||||
-17.467662811279297
|
||||
8.42333698272705,
|
||||
-16.937246322631836
|
||||
],
|
||||
[
|
||||
9.311224937438965,
|
||||
-11.442724227905273
|
||||
8.639735221862793,
|
||||
-17.410985946655273
|
||||
],
|
||||
[
|
||||
8.525369644165039,
|
||||
-11.465954780578613
|
||||
1.1124024391174316,
|
||||
-17.468708038330078
|
||||
]
|
||||
]
|
||||
},
|
||||
@ -96,20 +97,20 @@
|
||||
"name": "editor_obstacle_4",
|
||||
"polygon": [
|
||||
[
|
||||
8.59122085571289,
|
||||
-11.583345413208008
|
||||
1.952521800994873,
|
||||
-13.470939636230469
|
||||
],
|
||||
[
|
||||
8.580953598022461,
|
||||
-11.144271850585938
|
||||
1.947329044342041,
|
||||
-13.262446403503418
|
||||
],
|
||||
[
|
||||
3.9417855739593506,
|
||||
-11.05494213104248
|
||||
1.2782373428344727,
|
||||
-13.2465238571167
|
||||
],
|
||||
[
|
||||
3.879462718963623,
|
||||
-11.607364654541016
|
||||
1.2633711099624634,
|
||||
-13.548421859741211
|
||||
]
|
||||
]
|
||||
},
|
||||
@ -117,20 +118,20 @@
|
||||
"name": "editor_obstacle_5",
|
||||
"polygon": [
|
||||
[
|
||||
4.017904758453369,
|
||||
-11.611408233642578
|
||||
2.958512783050537,
|
||||
-13.523996353149414
|
||||
],
|
||||
[
|
||||
4.006087303161621,
|
||||
-13.59709644317627
|
||||
2.934694528579712,
|
||||
-13.240300178527832
|
||||
],
|
||||
[
|
||||
3.777372121810913,
|
||||
-13.521135330200195
|
||||
3.9795844554901123,
|
||||
-13.26203727722168
|
||||
],
|
||||
[
|
||||
3.7294042110443115,
|
||||
-11.210392951965332
|
||||
3.9670143127441406,
|
||||
-13.51730728149414
|
||||
]
|
||||
]
|
||||
},
|
||||
@ -138,20 +139,20 @@
|
||||
"name": "editor_obstacle_6",
|
||||
"polygon": [
|
||||
[
|
||||
2.783853769302368,
|
||||
-13.538301467895508
|
||||
3.643568992614746,
|
||||
-13.285079956054688
|
||||
],
|
||||
[
|
||||
2.766845703125,
|
||||
-13.329962730407715
|
||||
3.648775577545166,
|
||||
-11.270064353942871
|
||||
],
|
||||
[
|
||||
3.921206474304199,
|
||||
-13.34058952331543
|
||||
3.9994444847106934,
|
||||
-11.282587051391602
|
||||
],
|
||||
[
|
||||
3.937540054321289,
|
||||
-13.572001457214355
|
||||
3.920609474182129,
|
||||
-13.174944877624512
|
||||
]
|
||||
]
|
||||
},
|
||||
@ -159,20 +160,79 @@
|
||||
"name": "editor_obstacle_7",
|
||||
"polygon": [
|
||||
[
|
||||
2.046168327331543,
|
||||
-13.493659019470215
|
||||
1.3403878211975098,
|
||||
-11.485700607299805
|
||||
],
|
||||
[
|
||||
2.006760597229004,
|
||||
-13.261573791503906
|
||||
8.704232215881348,
|
||||
-11.600449562072754
|
||||
],
|
||||
[
|
||||
1.1306328773498535,
|
||||
-13.21288776397705
|
||||
8.6791410446167,
|
||||
-11.190678596496582
|
||||
],
|
||||
[
|
||||
1.190417766571045,
|
||||
-13.537941932678223
|
||||
1.2627182006835938,
|
||||
-10.95035457611084
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_1",
|
||||
"polygon": [
|
||||
[
|
||||
5.460248947143555,
|
||||
-16.92827796936035
|
||||
],
|
||||
[
|
||||
5.473773956298828,
|
||||
-15.50655746459961
|
||||
],
|
||||
[
|
||||
8.639936447143555,
|
||||
-15.49016284942627
|
||||
],
|
||||
[
|
||||
8.641860961914063,
|
||||
-17.03392791748047
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_2",
|
||||
"polygon": [
|
||||
[
|
||||
4.033830165863037,
|
||||
-12.481351852416992
|
||||
],
|
||||
[
|
||||
6.007711887359619,
|
||||
-12.465056419372559
|
||||
],
|
||||
[
|
||||
6.156071186065674,
|
||||
-11.502941131591797
|
||||
],
|
||||
[
|
||||
4.018871784210205,
|
||||
-11.45417594909668
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_3",
|
||||
"polygon": [
|
||||
[
|
||||
3.942854404449463,
|
||||
-13.410148620605469
|
||||
],
|
||||
[
|
||||
3.99332594871521,
|
||||
-12.681471824645996
|
||||
],
|
||||
[
|
||||
4.6172685623168945,
|
||||
-12.7000093460083
|
||||
]
|
||||
]
|
||||
},
|
||||
@ -180,42 +240,106 @@
|
||||
"name": "editor_obstacle_8",
|
||||
"polygon": [
|
||||
[
|
||||
1.2021913528442383,
|
||||
-14.716050148010254
|
||||
8.662647247314453,
|
||||
-11.577871322631836
|
||||
],
|
||||
[
|
||||
1.3182783126831055,
|
||||
-11.532548904418945
|
||||
8.59707260131836,
|
||||
-17.01089096069336
|
||||
],
|
||||
[
|
||||
1.0644679069519043,
|
||||
-11.525135040283203
|
||||
8.989262580871582,
|
||||
-16.998661041259766
|
||||
],
|
||||
[
|
||||
0.9918317794799805,
|
||||
-14.802279472351074
|
||||
9.054760932922363,
|
||||
-11.652122497558594
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_9",
|
||||
"name": "editor_obstacle_1x",
|
||||
"polygon": [
|
||||
[
|
||||
1.2470345497131348,
|
||||
-11.599748611450195
|
||||
2.8632972240448,
|
||||
-4.288420677185059
|
||||
],
|
||||
[
|
||||
3.9473354816436768,
|
||||
-11.655533790588379
|
||||
2.4562156200408936,
|
||||
-4.224598407745361
|
||||
],
|
||||
[
|
||||
3.9574456214904785,
|
||||
-11.309428215026855
|
||||
2.397826910018921,
|
||||
-5.586108684539795
|
||||
],
|
||||
[
|
||||
1.2795448303222656,
|
||||
-11.27739143371582
|
||||
2.843082904815674,
|
||||
-5.562361717224121
|
||||
]
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_2x",
|
||||
"polygon": [
|
||||
[
|
||||
2.669132709503174,
|
||||
-5.488218307495117
|
||||
],
|
||||
[
|
||||
8.675596237182617,
|
||||
-5.436037540435791
|
||||
],
|
||||
[
|
||||
8.74371337890625,
|
||||
-6.103575706481934
|
||||
],
|
||||
[
|
||||
2.6533708572387695,
|
||||
-6.057576656341553
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_3x",
|
||||
"polygon": [
|
||||
[
|
||||
2.490814208984375,
|
||||
-2.175637722015381
|
||||
],
|
||||
[
|
||||
2.5649731159210205,
|
||||
5.601792812347412
|
||||
],
|
||||
[
|
||||
9.002458572387695,
|
||||
5.9258809089660645
|
||||
],
|
||||
[
|
||||
8.68370532989502,
|
||||
-2.235023021697998
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_4x",
|
||||
"polygon": [
|
||||
[
|
||||
6.314299583435059,
|
||||
-2.1619086265563965
|
||||
],
|
||||
[
|
||||
6.418157577514648,
|
||||
-5.558330535888672
|
||||
],
|
||||
[
|
||||
8.6978759765625,
|
||||
-5.538100242614746
|
||||
],
|
||||
[
|
||||
8.630842208862305,
|
||||
-2.2032206058502197
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
367
resources/config2/navigation_dorm_tutorial001.json
Normal file
367
resources/config2/navigation_dorm_tutorial001.json
Normal file
@ -0,0 +1,367 @@
|
||||
{
|
||||
"cellSize": 0.1,
|
||||
"agentRadius": 0.25,
|
||||
"floorY": 0.0,
|
||||
"objectPadding": 0.15,
|
||||
"boundaryPadding": 0.15,
|
||||
"areas": [
|
||||
{
|
||||
"name": "main_corridor",
|
||||
"available": true,
|
||||
"polygon": [
|
||||
[
|
||||
-100,
|
||||
100
|
||||
],
|
||||
[
|
||||
100,
|
||||
100
|
||||
],
|
||||
[
|
||||
100,
|
||||
-100
|
||||
],
|
||||
[
|
||||
-100,
|
||||
-100
|
||||
]
|
||||
]
|
||||
}
|
||||
],
|
||||
"obstacles": [
|
||||
|
||||
{
|
||||
"name": "editor_obstacle_1",
|
||||
"polygon": [
|
||||
[
|
||||
1.2386366128921509,
|
||||
-16.910831451416016
|
||||
],
|
||||
[
|
||||
1.2082710266113281,
|
||||
-15.74820327758789
|
||||
],
|
||||
[
|
||||
0.9836082458496094,
|
||||
-15.767669677734375
|
||||
],
|
||||
[
|
||||
0.9937065839767456,
|
||||
-16.89757537841797
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_2",
|
||||
"polygon": [
|
||||
[
|
||||
1.2371597290039063,
|
||||
-14.667628288269043
|
||||
],
|
||||
[
|
||||
1.0021405220031738,
|
||||
-14.565974235534668
|
||||
],
|
||||
[
|
||||
0.8893742561340332,
|
||||
-11.02865982055664
|
||||
],
|
||||
[
|
||||
1.2916733026504517,
|
||||
-11.256534576416016
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_3",
|
||||
"polygon": [
|
||||
[
|
||||
1.15517258644104,
|
||||
-16.825780868530273
|
||||
],
|
||||
[
|
||||
8.42333698272705,
|
||||
-16.937246322631836
|
||||
],
|
||||
[
|
||||
8.639735221862793,
|
||||
-17.410985946655273
|
||||
],
|
||||
[
|
||||
1.1124024391174316,
|
||||
-17.468708038330078
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_4",
|
||||
"polygon": [
|
||||
[
|
||||
1.952521800994873,
|
||||
-13.470939636230469
|
||||
],
|
||||
[
|
||||
1.947329044342041,
|
||||
-13.262446403503418
|
||||
],
|
||||
[
|
||||
1.2782373428344727,
|
||||
-13.2465238571167
|
||||
],
|
||||
[
|
||||
1.2633711099624634,
|
||||
-13.548421859741211
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_5",
|
||||
"polygon": [
|
||||
[
|
||||
2.958512783050537,
|
||||
-13.523996353149414
|
||||
],
|
||||
[
|
||||
2.934694528579712,
|
||||
-13.240300178527832
|
||||
],
|
||||
[
|
||||
3.9795844554901123,
|
||||
-13.26203727722168
|
||||
],
|
||||
[
|
||||
3.9670143127441406,
|
||||
-13.51730728149414
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_6",
|
||||
"polygon": [
|
||||
[
|
||||
3.643568992614746,
|
||||
-13.285079956054688
|
||||
],
|
||||
[
|
||||
3.648775577545166,
|
||||
-11.270064353942871
|
||||
],
|
||||
[
|
||||
3.9994444847106934,
|
||||
-11.282587051391602
|
||||
],
|
||||
[
|
||||
3.920609474182129,
|
||||
-13.174944877624512
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_7",
|
||||
"polygon": [
|
||||
[
|
||||
1.3403878211975098,
|
||||
-11.485700607299805
|
||||
],
|
||||
[
|
||||
8.704232215881348,
|
||||
-11.600449562072754
|
||||
],
|
||||
[
|
||||
8.6791410446167,
|
||||
-11.190678596496582
|
||||
],
|
||||
[
|
||||
1.2627182006835938,
|
||||
-10.95035457611084
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_8",
|
||||
"polygon": [
|
||||
[
|
||||
8.662647247314453,
|
||||
-11.577871322631836
|
||||
],
|
||||
[
|
||||
8.59707260131836,
|
||||
-17.01089096069336
|
||||
],
|
||||
[
|
||||
8.989262580871582,
|
||||
-16.998661041259766
|
||||
],
|
||||
[
|
||||
9.054760932922363,
|
||||
-11.652122497558594
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_1x",
|
||||
"polygon": [
|
||||
[
|
||||
2.8632972240448,
|
||||
-4.288420677185059
|
||||
],
|
||||
[
|
||||
2.4562156200408936,
|
||||
-4.224598407745361
|
||||
],
|
||||
[
|
||||
2.397826910018921,
|
||||
-5.586108684539795
|
||||
],
|
||||
[
|
||||
2.843082904815674,
|
||||
-5.562361717224121
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_2x",
|
||||
"polygon": [
|
||||
[
|
||||
2.669132709503174,
|
||||
-5.488218307495117
|
||||
],
|
||||
[
|
||||
8.675596237182617,
|
||||
-5.436037540435791
|
||||
],
|
||||
[
|
||||
8.74371337890625,
|
||||
-6.103575706481934
|
||||
],
|
||||
[
|
||||
2.6533708572387695,
|
||||
-6.057576656341553
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_3x",
|
||||
"polygon": [
|
||||
[
|
||||
2.490814208984375,
|
||||
-2.175637722015381
|
||||
],
|
||||
[
|
||||
2.5649731159210205,
|
||||
5.601792812347412
|
||||
],
|
||||
[
|
||||
9.002458572387695,
|
||||
5.9258809089660645
|
||||
],
|
||||
[
|
||||
8.68370532989502,
|
||||
-2.235023021697998
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_4x",
|
||||
"polygon": [
|
||||
[
|
||||
6.314299583435059,
|
||||
-2.1619086265563965
|
||||
],
|
||||
[
|
||||
6.418157577514648,
|
||||
-5.558330535888672
|
||||
],
|
||||
[
|
||||
8.6978759765625,
|
||||
-5.538100242614746
|
||||
],
|
||||
[
|
||||
8.630842208862305,
|
||||
-2.2032206058502197
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_1",
|
||||
"polygon": [
|
||||
[
|
||||
5.460248947143555,
|
||||
-16.92827796936035
|
||||
],
|
||||
[
|
||||
5.473773956298828,
|
||||
-15.50655746459961
|
||||
],
|
||||
[
|
||||
8.639936447143555,
|
||||
-15.49016284942627
|
||||
],
|
||||
[
|
||||
8.641860961914063,
|
||||
-17.03392791748047
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_2",
|
||||
"polygon": [
|
||||
[
|
||||
4.033830165863037,
|
||||
-12.481351852416992
|
||||
],
|
||||
[
|
||||
6.007711887359619,
|
||||
-12.465056419372559
|
||||
],
|
||||
[
|
||||
6.156071186065674,
|
||||
-11.502941131591797
|
||||
],
|
||||
[
|
||||
4.018871784210205,
|
||||
-11.45417594909668
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "editor_obstacle_3",
|
||||
"polygon": [
|
||||
[
|
||||
3.942854404449463,
|
||||
-13.410148620605469
|
||||
],
|
||||
[
|
||||
3.99332594871521,
|
||||
-12.681471824645996
|
||||
],
|
||||
[
|
||||
4.6172685623168945,
|
||||
-12.7000093460083
|
||||
]
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "dialog_start_block001",
|
||||
"polygon": [
|
||||
[
|
||||
0.9441208839416504,
|
||||
-14.674051284790039
|
||||
],
|
||||
[
|
||||
1.351646900177002,
|
||||
-14.717156410217285
|
||||
],
|
||||
[
|
||||
1.3264522552490234,
|
||||
-15.757955551147461
|
||||
],
|
||||
[
|
||||
0.9525976181030273,
|
||||
-15.736042976379395
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
4
resources/config2/trigger_zones.json
Normal file
4
resources/config2/trigger_zones.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"trigger_zones": [
|
||||
]
|
||||
}
|
||||
4
resources/config2/trigger_zones2.json
Normal file
4
resources/config2/trigger_zones2.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"trigger_zones": [
|
||||
]
|
||||
}
|
||||
22
resources/config2/trigger_zones_dorm.json
Normal file
22
resources/config2/trigger_zones_dorm.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"trigger_zones": [
|
||||
{
|
||||
"id": "pickup_phone_zone001",
|
||||
"positionX": 2.54938,
|
||||
"positionY": 0.0,
|
||||
"positionZ": -15.2422,
|
||||
"radius": 1.0,
|
||||
"hysteresis": 0.1,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": "ladder_zone001",
|
||||
"positionX": 3.7569,
|
||||
"positionY": 0.0,
|
||||
"positionZ": -3.50058,
|
||||
"radius": 2.0,
|
||||
"hysteresis": 0.1,
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -25,6 +25,60 @@
|
||||
"type": "End"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "dialog_phone001",
|
||||
"start": "line_1",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "line_1",
|
||||
"type": "Line",
|
||||
"speaker": "Бекзат",
|
||||
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
|
||||
"text": "Я не буду никуда идти без своего телефона и записной книжки!",
|
||||
"next": "end_1"
|
||||
},
|
||||
{
|
||||
"id": "end_1",
|
||||
"type": "End"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "dialog_phone_pickup001",
|
||||
"start": "line_1",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "line_1",
|
||||
"type": "Line",
|
||||
"speaker": "Бекзат",
|
||||
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
|
||||
"text": "Отлично, вот и мой телефон! Надо проверить новые сообщения.",
|
||||
"next": "end_1"
|
||||
},
|
||||
{
|
||||
"id": "end_1",
|
||||
"type": "End"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "dialog_journal_pickup001",
|
||||
"start": "line_1",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "line_1",
|
||||
"type": "Line",
|
||||
"speaker": "Бекзат",
|
||||
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
|
||||
"text": "Возьму журнал с собой! Там все мои записи.",
|
||||
"next": "end_1"
|
||||
},
|
||||
{
|
||||
"id": "end_1",
|
||||
"type": "End"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "dialog_taxi001",
|
||||
|
||||
@ -14,4 +14,48 @@ step1()
|
||||
|
||||
game_api.start_dialogue("dialog_start001")
|
||||
|
||||
phone_picked_up = false
|
||||
journal_picked_up = false
|
||||
|
||||
|
||||
function on_phone_pickup()
|
||||
game_api.pickup_item("phone")
|
||||
game_api.start_dialogue("dialog_phone_pickup001")
|
||||
phone_picked_up = true
|
||||
end
|
||||
|
||||
function on_journal_pickup()
|
||||
game_api.pickup_item("journal")
|
||||
game_api.start_dialogue("dialog_journal_pickup001")
|
||||
journal_picked_up = true
|
||||
end
|
||||
|
||||
function pickup_phone_zone001_enter_callback()
|
||||
print("pickup_phone_zone001_enter_callback--!")
|
||||
if (not phone_picked_up) or (not journal_picked_up) then
|
||||
game_api.start_dialogue("dialog_phone001")
|
||||
game_api.switch_navigation(1)
|
||||
end
|
||||
end
|
||||
|
||||
function pickup_phone_zone001_exit_callback()
|
||||
print("pickup_phone_zone001_exit_callback--!")
|
||||
game_api.switch_navigation(0)
|
||||
end
|
||||
|
||||
game_api.set_trigger_zone_callbacks("pickup_phone_zone001",
|
||||
pickup_phone_zone001_enter_callback,
|
||||
pickup_phone_zone001_exit_callback
|
||||
)
|
||||
|
||||
function ladder_zone001_enter_callback()
|
||||
game_api.start_dialogue("dialog_second_floor001")
|
||||
end
|
||||
|
||||
game_api.set_trigger_zone_callbacks("ladder_zone001",
|
||||
ladder_zone001_enter_callback,
|
||||
nil
|
||||
)
|
||||
|
||||
|
||||
print("Lua script loaded successfully--!")
|
||||
5254
resources/w/dorm/ikea_bed001.txt
Normal file
5254
resources/w/dorm/ikea_bed001.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
resources/w/dorm/ikea_bed_bake002.png
(Stored with Git LFS)
Normal file
BIN
resources/w/dorm/ikea_bed_bake002.png
(Stored with Git LFS)
Normal file
Binary file not shown.
29219
resources/w/dorm/ikea_chair001.txt
Normal file
29219
resources/w/dorm/ikea_chair001.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
resources/w/dorm/ikea_chair_bake002.png
(Stored with Git LFS)
Normal file
BIN
resources/w/dorm/ikea_chair_bake002.png
(Stored with Git LFS)
Normal file
Binary file not shown.
81623
resources/w/dorm/ikea_table001.txt
Normal file
81623
resources/w/dorm/ikea_table001.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
resources/w/dorm/ikea_table_bake003.png
(Stored with Git LFS)
Normal file
BIN
resources/w/dorm/ikea_table_bake003.png
(Stored with Git LFS)
Normal file
Binary file not shown.
39
resources/w/dorm/journal001.txt
Normal file
39
resources/w/dorm/journal001.txt
Normal file
@ -0,0 +1,39 @@
|
||||
===Vertices (Split by UV/Normal): 24
|
||||
V 0: Pos(0.26, 0.15, 0.02) Norm(0.577351, 0.57735, 0.57735) UV(0.944444, 0.416667)
|
||||
V 1: Pos(0.26, -0.15, -0.02) Norm(0.577351, -0.57735, -0.57735) UV(1.0, 0.0)
|
||||
V 2: Pos(0.26, 0.15, -0.02) Norm(0.577349, 0.577358, -0.577343) UV(1.0, 0.416667)
|
||||
V 3: Pos(0.26, -0.15, 0.02) Norm(0.577349, -0.577358, 0.577343) UV(0.833333, 0.722223)
|
||||
V 4: Pos(-0.26, -0.15, -0.02) Norm(-0.577349, -0.577358, -0.577343) UV(0.888889, 0.0)
|
||||
V 5: Pos(0.26, -0.15, -0.02) Norm(0.577351, -0.57735, -0.57735) UV(0.888889, 0.722223)
|
||||
V 6: Pos(-0.26, -0.15, 0.02) Norm(-0.577351, -0.57735, 0.57735) UV(0.944444, 0.833334)
|
||||
V 7: Pos(-0.26, 0.15, -0.02) Norm(-0.577351, 0.57735, -0.57735) UV(1.0, 0.416667)
|
||||
V 8: Pos(-0.26, -0.15, -0.02) Norm(-0.577349, -0.577358, -0.577343) UV(1.0, 0.833334)
|
||||
V 9: Pos(-0.26, 0.15, 0.02) Norm(-0.577349, 0.577358, 0.577343) UV(0.888889, 0.722223)
|
||||
V 10: Pos(0.26, 0.15, -0.02) Norm(0.577349, 0.577358, -0.577343) UV(0.944445, 0.0)
|
||||
V 11: Pos(-0.26, 0.15, -0.02) Norm(-0.577351, 0.57735, -0.57735) UV(0.944444, 0.722223)
|
||||
V 12: Pos(-0.26, -0.15, -0.02) Norm(-0.577349, -0.577358, -0.577343) UV(0.0, 0.0)
|
||||
V 13: Pos(0.26, 0.15, -0.02) Norm(0.577349, 0.577358, -0.577343) UV(0.416667, 0.722223)
|
||||
V 14: Pos(0.26, -0.15, -0.02) Norm(0.577351, -0.57735, -0.57735) UV(-0.0, 0.722223)
|
||||
V 15: Pos(0.26, -0.15, 0.02) Norm(0.577349, -0.577358, 0.577343) UV(0.416667, 0.0)
|
||||
V 16: Pos(-0.26, 0.15, 0.02) Norm(-0.577349, 0.577358, 0.577343) UV(0.833333, 0.722223)
|
||||
V 17: Pos(-0.26, -0.15, 0.02) Norm(-0.577351, -0.57735, 0.57735) UV(0.416667, 0.722223)
|
||||
V 18: Pos(0.26, -0.15, 0.02) Norm(0.577349, -0.577358, 0.577343) UV(0.944445, 0.0)
|
||||
V 19: Pos(-0.26, -0.15, 0.02) Norm(-0.577351, -0.57735, 0.57735) UV(0.833334, 0.0)
|
||||
V 20: Pos(-0.26, 0.15, 0.02) Norm(-0.577349, 0.577358, 0.577343) UV(0.944444, 0.416667)
|
||||
V 21: Pos(0.26, 0.15, 0.02) Norm(0.577351, 0.57735, 0.57735) UV(0.888889, 0.0)
|
||||
V 22: Pos(-0.26, 0.15, -0.02) Norm(-0.577351, 0.57735, -0.57735) UV(0.416667, 0.0)
|
||||
V 23: Pos(0.26, 0.15, 0.02) Norm(0.577351, 0.57735, 0.57735) UV(0.833334, 0.0)
|
||||
|
||||
===Triangles (Indices): 12
|
||||
Tri: 0 1 2
|
||||
Tri: 3 4 5
|
||||
Tri: 6 7 8
|
||||
Tri: 9 10 11
|
||||
Tri: 12 13 14
|
||||
Tri: 15 16 17
|
||||
Tri: 0 18 1
|
||||
Tri: 3 19 4
|
||||
Tri: 6 20 7
|
||||
Tri: 9 21 10
|
||||
Tri: 12 22 13
|
||||
Tri: 15 23 16
|
||||
BIN
resources/w/dorm/journal001_tex002.png
(Stored with Git LFS)
Normal file
BIN
resources/w/dorm/journal001_tex002.png
(Stored with Git LFS)
Normal file
Binary file not shown.
39
resources/w/dorm/phone001.txt
Normal file
39
resources/w/dorm/phone001.txt
Normal file
@ -0,0 +1,39 @@
|
||||
===Vertices (Split by UV/Normal): 24
|
||||
V 0: Pos(0.180001, 0.08, 0.02) Norm(0.577335, 0.577358, 0.577358) UV(0.909091, 0.363636)
|
||||
V 1: Pos(0.180001, -0.08, -0.02) Norm(0.577335, -0.577358, -0.577358) UV(1.0, 0.0)
|
||||
V 2: Pos(0.180001, 0.08, -0.02) Norm(0.577357, 0.577362, -0.577332) UV(1.0, 0.363636)
|
||||
V 3: Pos(0.180001, -0.08, 0.02) Norm(0.577357, -0.577362, 0.577332) UV(0.727273, 0.818184)
|
||||
V 4: Pos(-0.179999, -0.08, -0.02) Norm(-0.577357, -0.577362, -0.577332) UV(0.818182, 0.0)
|
||||
V 5: Pos(0.180001, -0.08, -0.02) Norm(0.577335, -0.577358, -0.577358) UV(0.818182, 0.818184)
|
||||
V 6: Pos(-0.179999, -0.08, 0.02) Norm(-0.577335, -0.577358, 0.577358) UV(0.909091, 0.727273)
|
||||
V 7: Pos(-0.179999, 0.08, -0.02) Norm(-0.577335, 0.577358, -0.577358) UV(1.0, 0.363636)
|
||||
V 8: Pos(-0.179999, -0.08, -0.02) Norm(-0.577357, -0.577362, -0.577332) UV(1.0, 0.727273)
|
||||
V 9: Pos(-0.179999, 0.08, 0.02) Norm(-0.577357, 0.577362, 0.577332) UV(0.818182, 0.818184)
|
||||
V 10: Pos(0.180001, 0.08, -0.02) Norm(0.577357, 0.577362, -0.577332) UV(0.909091, 0.0)
|
||||
V 11: Pos(-0.179999, 0.08, -0.02) Norm(-0.577335, 0.577358, -0.577358) UV(0.909091, 0.818184)
|
||||
V 12: Pos(-0.179999, -0.08, -0.02) Norm(-0.577357, -0.577362, -0.577332) UV(0.0, 0.0)
|
||||
V 13: Pos(0.180001, 0.08, -0.02) Norm(0.577357, 0.577362, -0.577332) UV(0.363636, 0.818184)
|
||||
V 14: Pos(0.180001, -0.08, -0.02) Norm(0.577335, -0.577358, -0.577358) UV(-0.0, 0.818184)
|
||||
V 15: Pos(0.180001, -0.08, 0.02) Norm(0.577357, -0.577362, 0.577332) UV(0.363636, 0.0)
|
||||
V 16: Pos(-0.179999, 0.08, 0.02) Norm(-0.577357, 0.577362, 0.577332) UV(0.727273, 0.818184)
|
||||
V 17: Pos(-0.179999, -0.08, 0.02) Norm(-0.577335, -0.577358, 0.577358) UV(0.363636, 0.818184)
|
||||
V 18: Pos(0.180001, -0.08, 0.02) Norm(0.577357, -0.577362, 0.577332) UV(0.909091, 0.0)
|
||||
V 19: Pos(-0.179999, -0.08, 0.02) Norm(-0.577335, -0.577358, 0.577358) UV(0.727273, 0.0)
|
||||
V 20: Pos(-0.179999, 0.08, 0.02) Norm(-0.577357, 0.577362, 0.577332) UV(0.909091, 0.363636)
|
||||
V 21: Pos(0.180001, 0.08, 0.02) Norm(0.577335, 0.577358, 0.577358) UV(0.818182, 0.0)
|
||||
V 22: Pos(-0.179999, 0.08, -0.02) Norm(-0.577335, 0.577358, -0.577358) UV(0.363636, 0.0)
|
||||
V 23: Pos(0.180001, 0.08, 0.02) Norm(0.577335, 0.577358, 0.577358) UV(0.727273, 0.0)
|
||||
|
||||
===Triangles (Indices): 12
|
||||
Tri: 0 1 2
|
||||
Tri: 3 4 5
|
||||
Tri: 6 7 8
|
||||
Tri: 9 10 11
|
||||
Tri: 12 13 14
|
||||
Tri: 15 16 17
|
||||
Tri: 0 18 1
|
||||
Tri: 3 19 4
|
||||
Tri: 6 20 7
|
||||
Tri: 9 21 10
|
||||
Tri: 12 22 13
|
||||
Tri: 15 23 16
|
||||
BIN
resources/w/dorm/phone001_tex001.png
(Stored with Git LFS)
Normal file
BIN
resources/w/dorm/phone001_tex001.png
(Stored with Git LFS)
Normal file
Binary file not shown.
17
src/Game.cpp
17
src/Game.cpp
@ -164,8 +164,9 @@ namespace ZL
|
||||
params1.gameObjectsJsonPath = "resources/config2/gameobjects.json";
|
||||
params1.npcsJsonPath = "resources/config2/npcs.json";
|
||||
params1.dialoguesJsonPath = "resources/dialogue/sample_dialogues.json";
|
||||
params1.navigationJsonPath = "resources/config2/navigation.json";
|
||||
params1.navigationJsonPaths = {"resources/config2/navigation.json"};
|
||||
params1.teleportsJsonPath = "resources/config2/teleports.json";
|
||||
params1.triggerZonesJsonPath = "resources/config2/trigger_zones.json";
|
||||
params1.scriptPath = "resources/start.lua";
|
||||
params1.playerPosition = Eigen::Vector3f(0.942694, 0, -9.63104);
|
||||
|
||||
@ -176,8 +177,9 @@ namespace ZL
|
||||
params2.roomMeshPath = "resources/w/exterior/Segmented_Plane002.txt";
|
||||
params2.roomTexturePath = "resources/w/exterior/Segmented_Plane002.png";
|
||||
params2.gameObjectsJsonPath = "resources/config2/gameobjects2.json";
|
||||
params2.navigationJsonPath = "resources/config2/navigation2.json";
|
||||
params2.navigationJsonPaths = {"resources/config2/navigation2.json"};
|
||||
params2.teleportsJsonPath = "resources/config2/teleports2.json";
|
||||
params2.triggerZonesJsonPath = "resources/config2/trigger_zones2.json";
|
||||
params2.scriptPath = "resources/start2.lua";
|
||||
params2.playerPosition = Eigen::Vector3f(5, 0, -18.4);
|
||||
params2.npcsJsonPath = "resources/config2/npcs2.json";
|
||||
@ -191,11 +193,11 @@ namespace ZL
|
||||
params_dorm.gameObjectsJsonPath = "resources/config2/gameobjects_dorm.json";
|
||||
params_dorm.npcsJsonPath = "resources/config2/npcs_dorm.json";
|
||||
params_dorm.dialoguesJsonPath = "resources/dialogue/dorm_dialogues.json";
|
||||
params_dorm.navigationJsonPath = "resources/config2/navigation_dorm.json";
|
||||
params_dorm.navigationJsonPaths = {"resources/config2/navigation_dorm.json", "resources/config2/navigation_dorm_tutorial001.json" };
|
||||
params_dorm.teleportsJsonPath = "resources/config2/teleports_dorm.json";
|
||||
params_dorm.triggerZonesJsonPath = "resources/config2/trigger_zones_dorm.json";
|
||||
params_dorm.scriptPath = "resources/start_dorm.lua";
|
||||
params_dorm.playerPosition = Eigen::Vector3f(6.0357, 0, -16.0581);
|
||||
|
||||
params_dorm.playerPosition = Eigen::Vector3f(6.76345, 0, -14.6022);
|
||||
|
||||
locations["location_dorm"] = std::make_shared<Location>(renderer, inventory);
|
||||
locations["location_dorm"]->setup(params_dorm);
|
||||
@ -534,15 +536,14 @@ namespace ZL
|
||||
case SDLK_o:
|
||||
//y = y + 0.002;
|
||||
//currentLocation->player->hp = 200;
|
||||
currentLocation->npcs[0]->walkSpeed += 0.02f;
|
||||
currentLocation->npcs[0]->walkSpeed += 0.01f;
|
||||
std::cout << "Walk speed: " << currentLocation->npcs[0]->walkSpeed << std::endl;
|
||||
|
||||
break;
|
||||
|
||||
case SDLK_k:
|
||||
//y = y - 0.002;
|
||||
std::cout << "Player pos: " << currentLocation->player->position.transpose() << std::endl;
|
||||
currentLocation->npcs[0]->walkSpeed -= 0.02f;
|
||||
currentLocation->npcs[0]->walkSpeed -= 0.01f;
|
||||
std::cout << "Walk speed: " << currentLocation->npcs[0]->walkSpeed << std::endl;
|
||||
break;
|
||||
|
||||
|
||||
142
src/Location.cpp
142
src/Location.cpp
@ -137,6 +137,7 @@ namespace ZL
|
||||
}
|
||||
|
||||
loadTeleportZones(params.teleportsJsonPath, CONST_ZIP_FILE);
|
||||
loadTriggerZones(params.triggerZonesJsonPath, CONST_ZIP_FILE);
|
||||
|
||||
#ifndef EMSCRIPTEN
|
||||
// Create shadow map (2048x2048, ortho size 40, near 0.1, far 100)
|
||||
@ -145,7 +146,7 @@ namespace ZL
|
||||
std::cout << "Shadow map initialized" << std::endl;
|
||||
#endif
|
||||
|
||||
setupNavigation(params.navigationJsonPath);
|
||||
setupNavigation(params.navigationJsonPaths);
|
||||
|
||||
dialogueSystem.init(renderer, CONST_ZIP_FILE);
|
||||
dialogueSystem.loadDatabase(params.dialoguesJsonPath);
|
||||
@ -165,7 +166,7 @@ namespace ZL
|
||||
false
|
||||
});*/
|
||||
|
||||
navigationEditorConfigPath = params.navigationJsonPath;
|
||||
// navigationMapPaths is already populated by setupNavigation
|
||||
|
||||
scriptEngine.init(this, &inventory, params.scriptPath);
|
||||
|
||||
@ -231,13 +232,84 @@ namespace ZL
|
||||
std::cout << "[TELEPORT] Loaded " << teleportZones.size() << " teleport(s) from " << jsonPath << std::endl;
|
||||
}
|
||||
|
||||
void Location::setupNavigation(const std::string& navigationJsonPath)
|
||||
void Location::loadTriggerZones(const std::string& jsonPath, const char* zipFile)
|
||||
{
|
||||
// Static navigation blockers are defined in the navigation JSON as polygons.
|
||||
// NPC + player are handled as dynamic obstacles, so they are intentionally NOT in JSON.
|
||||
navigation.build({}, navigationJsonPath, CONST_ZIP_FILE);
|
||||
if (jsonPath.empty()) return;
|
||||
|
||||
if (navigationEditorMode) {
|
||||
std::string content;
|
||||
try {
|
||||
if (!zipFile || zipFile[0] == '\0') {
|
||||
content = readTextFile(jsonPath);
|
||||
} else {
|
||||
auto buf = readFileFromZIP(jsonPath, zipFile);
|
||||
if (buf.empty()) {
|
||||
std::cerr << "[TRIGGER] Failed to read " << jsonPath << " from zip" << std::endl;
|
||||
return;
|
||||
}
|
||||
content.assign(buf.begin(), buf.end());
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "[TRIGGER] Failed to open " << jsonPath << ": " << e.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
using json = nlohmann::json;
|
||||
json j;
|
||||
try {
|
||||
j = json::parse(content);
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "[TRIGGER] JSON parse error in " << jsonPath << ": " << e.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!j.contains("trigger_zones") || !j["trigger_zones"].is_array()) return;
|
||||
|
||||
for (const auto& item : j["trigger_zones"]) {
|
||||
TriggerZone tz;
|
||||
tz.id = item.value("id", "");
|
||||
tz.enabled = item.value("enabled", true);
|
||||
tz.radius = item.value("radius", 1.5f);
|
||||
tz.hysteresis = item.value("hysteresis", 0.3f);
|
||||
tz.position = Eigen::Vector3f(
|
||||
item.value("positionX", 0.0f),
|
||||
item.value("positionY", 0.0f),
|
||||
item.value("positionZ", 0.0f)
|
||||
);
|
||||
triggerZones.push_back(std::move(tz));
|
||||
}
|
||||
|
||||
std::cout << "[TRIGGER] Loaded " << triggerZones.size() << " trigger zone(s) from " << jsonPath << std::endl;
|
||||
}
|
||||
|
||||
void Location::updateTriggerZones(const Eigen::Vector3f& playerPos)
|
||||
{
|
||||
for (auto& tz : triggerZones) {
|
||||
if (!tz.enabled) continue;
|
||||
const float dist = (playerPos - tz.position).norm();
|
||||
if (!tz.playerInside && dist <= tz.radius) {
|
||||
tz.playerInside = true;
|
||||
scriptEngine.callTriggerEnterCallback(tz.id);
|
||||
} else if (tz.playerInside && dist > tz.radius + tz.hysteresis) {
|
||||
tz.playerInside = false;
|
||||
scriptEngine.callTriggerExitCallback(tz.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Location::setupNavigation(const std::vector<std::string>& paths)
|
||||
{
|
||||
navigationMapPaths = paths;
|
||||
navigationMaps.clear();
|
||||
navigationMaps.resize(paths.size());
|
||||
|
||||
for (size_t i = 0; i < paths.size(); ++i) {
|
||||
navigationMaps[i].build({}, paths[i], CONST_ZIP_FILE);
|
||||
}
|
||||
|
||||
activeNavigationIndex = 0;
|
||||
navigation = navigationMaps.empty() ? nullptr : &navigationMaps[0];
|
||||
|
||||
if (navigationEditorMode && navigation) {
|
||||
navigationEditorBuildNavMeshes();
|
||||
}
|
||||
|
||||
@ -245,6 +317,7 @@ namespace ZL
|
||||
|
||||
auto makePlanner = [this](const Character* self) {
|
||||
return [this, self](const Eigen::Vector3f& start, const Eigen::Vector3f& end) {
|
||||
if (!navigation) return std::vector<Eigen::Vector3f>{};
|
||||
std::vector<PathFinder::DynamicObstacle> dynamicObstacles;
|
||||
dynamicObstacles.reserve(npcs.size() + 1);
|
||||
|
||||
@ -257,7 +330,7 @@ namespace ZL
|
||||
}
|
||||
|
||||
PathFinder::DynamicObstacle obs;
|
||||
obs.position = Eigen::Vector3f(other->position.x(), navigation.getFloorY(), other->position.z());
|
||||
obs.position = Eigen::Vector3f(other->position.x(), navigation->getFloorY(), other->position.z());
|
||||
obs.radius = (std::max)(0.0f, other->collisionRadius);
|
||||
dynamicObstacles.push_back(obs);
|
||||
};
|
||||
@ -267,7 +340,7 @@ namespace ZL
|
||||
addCharacter(npc.get());
|
||||
}
|
||||
|
||||
return navigation.findPath(start, end, dynamicObstacles);
|
||||
return navigation->findPath(start, end, dynamicObstacles);
|
||||
};
|
||||
};
|
||||
|
||||
@ -282,12 +355,35 @@ namespace ZL
|
||||
}
|
||||
}
|
||||
|
||||
bool Location::switchNavigation(int index)
|
||||
{
|
||||
if (index < 0 || index >= static_cast<int>(navigationMaps.size())) {
|
||||
std::cerr << "[NAV] switchNavigation: index " << index << " out of range\n";
|
||||
return false;
|
||||
}
|
||||
activeNavigationIndex = index;
|
||||
navigation = &navigationMaps[index];
|
||||
|
||||
// Force all characters to replan their paths against the new nav map.
|
||||
if (player) player->forceReplan();
|
||||
for (auto& npc : npcs) {
|
||||
if (npc) npc->forceReplan();
|
||||
}
|
||||
|
||||
if (navigationEditorMode) {
|
||||
navigationEditorBuildNavMeshes();
|
||||
}
|
||||
std::cout << "[NAV] Switched to navigation map " << index << "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
void Location::navigationEditorBuildNavMeshes()
|
||||
{
|
||||
navigationEditorNavMeshes.clear();
|
||||
const float y = navigation.getFloorY() + 0.02f;
|
||||
if (!navigation) return;
|
||||
const float y = navigation->getFloorY() + 0.02f;
|
||||
const Eigen::Vector3f red(1.0f, 0.0f, 0.0f);
|
||||
for (const auto& obs : navigation.getObstaclePolygons()) {
|
||||
for (const auto& obs : navigation->getObstaclePolygons()) {
|
||||
if (obs.polygon.size() < 3) continue;
|
||||
VertexRenderStruct mesh;
|
||||
mesh.data = CreatePolygonFloor(obs.polygon, y, red);
|
||||
@ -311,7 +407,7 @@ namespace ZL
|
||||
{
|
||||
VertexDataStruct data;
|
||||
const Eigen::Vector3f yellow(1.0f, 1.0f, 0.0f);
|
||||
const float y = navigation.getFloorY() + 0.05f;
|
||||
const float y = navigation ? navigation->getFloorY() + 0.05f : 0.05f;
|
||||
const float s = 0.2f;
|
||||
|
||||
for (const auto& pt : navigationEditorPoints) {
|
||||
@ -381,13 +477,13 @@ namespace ZL
|
||||
poly.polygon.emplace_back(pt.x(), pt.z());
|
||||
}
|
||||
|
||||
navigation.addObstaclePolygon(poly);
|
||||
if (navigation) navigation->addObstaclePolygon(poly);
|
||||
std::cout << "[NAV_EDITOR] Added obstacle '" << poly.name << "' with "
|
||||
<< poly.polygon.size() << " vertices\n";
|
||||
|
||||
// Add a red mesh for the new obstacle polygon so it's visible immediately.
|
||||
{
|
||||
const float y = navigation.getFloorY() + 0.02f;
|
||||
const float y = navigation ? navigation->getFloorY() + 0.02f : 0.02f;
|
||||
const Eigen::Vector3f red(1.0f, 0.0f, 0.0f);
|
||||
VertexRenderStruct mesh;
|
||||
mesh.data = CreatePolygonFloor(poly.polygon, y, red);
|
||||
@ -409,7 +505,7 @@ namespace ZL
|
||||
if (!std::filesystem::exists(filename)) break;
|
||||
}
|
||||
|
||||
if (navigation.saveConfig(filename)) {
|
||||
if (navigation && navigation->saveConfig(filename)) {
|
||||
std::cout << "[NAV_EDITOR] Saved navigation config to: " << filename << "\n";
|
||||
} else {
|
||||
std::cerr << "[NAV_EDITOR] Failed to save to: " << filename << "\n";
|
||||
@ -418,8 +514,8 @@ namespace ZL
|
||||
|
||||
void Location::navigationEditorReload()
|
||||
{
|
||||
setupNavigation(navigationEditorConfigPath);
|
||||
std::cout << "[NAV_EDITOR] Reloaded navigation from: " << navigationEditorConfigPath << "\n";
|
||||
setupNavigation(navigationMapPaths);
|
||||
std::cout << "[NAV_EDITOR] Reloaded navigation maps (" << navigationMapPaths.size() << " maps)\n";
|
||||
}
|
||||
|
||||
|
||||
@ -821,7 +917,8 @@ namespace ZL
|
||||
|
||||
bool Location::setNavigationAreaAvailable(const std::string& areaName, bool available)
|
||||
{
|
||||
return navigation.setAreaAvailable(areaName, available);
|
||||
if (!navigation) return false;
|
||||
return navigation->setAreaAvailable(areaName, available);
|
||||
}
|
||||
|
||||
void Location::resolveCharacterCollisions()
|
||||
@ -882,9 +979,9 @@ namespace ZL
|
||||
newB.z() += normal.y() * push;
|
||||
newB.y() = 0.f;
|
||||
|
||||
if (navigation.isReady()) {
|
||||
const bool aOk = navigation.isWalkable(newA);
|
||||
const bool bOk = navigation.isWalkable(newB);
|
||||
if (navigation && navigation->isReady()) {
|
||||
const bool aOk = navigation->isWalkable(newA);
|
||||
const bool bOk = navigation->isWalkable(newB);
|
||||
|
||||
if (aOk && bOk) {
|
||||
a->position = newA;
|
||||
@ -978,7 +1075,8 @@ namespace ZL
|
||||
{
|
||||
if (player) {
|
||||
player->update(delta);
|
||||
dialogueSystem.update(static_cast<int>(delta), player->position);
|
||||
dialogueSystem.update(static_cast<int>(delta));
|
||||
updateTriggerZones(player->position);
|
||||
}
|
||||
for (auto& npc : npcs)
|
||||
{
|
||||
|
||||
@ -19,6 +19,16 @@
|
||||
namespace ZL
|
||||
{
|
||||
|
||||
struct TriggerZone
|
||||
{
|
||||
std::string id;
|
||||
Eigen::Vector3f position = Eigen::Vector3f::Zero();
|
||||
float radius = 1.5f;
|
||||
float hysteresis = 0.3f; // exit fires at radius + hysteresis to prevent flickering
|
||||
bool enabled = true;
|
||||
bool playerInside = false; // runtime tracking state, not serialized
|
||||
};
|
||||
|
||||
struct LocationSetup
|
||||
{
|
||||
std::string roomMeshPath;
|
||||
@ -26,9 +36,10 @@ namespace ZL
|
||||
std::string gameObjectsJsonPath;
|
||||
std::string npcsJsonPath;
|
||||
std::string dialoguesJsonPath;
|
||||
std::string navigationJsonPath;
|
||||
std::vector<std::string> navigationJsonPaths;
|
||||
std::string scriptPath;
|
||||
std::string teleportsJsonPath;
|
||||
std::string triggerZonesJsonPath;
|
||||
Eigen::Vector3f playerPosition = Eigen::Vector3f::Zero();
|
||||
};
|
||||
|
||||
@ -52,7 +63,9 @@ namespace ZL
|
||||
float cameraAzimuth = 0.0f;
|
||||
float cameraInclination = M_PI * 30.f / 180.f;
|
||||
|
||||
PathFinder navigation;
|
||||
std::vector<PathFinder> navigationMaps;
|
||||
PathFinder* navigation = nullptr;
|
||||
int activeNavigationIndex = 0;
|
||||
|
||||
std::unique_ptr<ShadowMap> shadowMap;
|
||||
Eigen::Matrix4f cameraViewMatrix = Eigen::Matrix4f::Identity();
|
||||
@ -73,13 +86,15 @@ namespace ZL
|
||||
TeleportZone* targetTeleportZone = nullptr;
|
||||
std::function<void(const std::string&, const Eigen::Vector3f&, float)> onTeleport;
|
||||
|
||||
std::vector<TriggerZone> triggerZones;
|
||||
|
||||
// Navigation editor — toggle with 'N', save with 'B', right-click to finalize polygon
|
||||
bool navigationEditorMode = false;
|
||||
|
||||
std::vector<Eigen::Vector3f> navigationEditorPoints;
|
||||
VertexRenderStruct navigationEditorPointsMesh;
|
||||
std::vector<VertexRenderStruct> navigationEditorNavMeshes;
|
||||
std::string navigationEditorConfigPath;
|
||||
std::vector<std::string> navigationMapPaths;
|
||||
int navigationEditorObstacleCounter = 0;
|
||||
|
||||
void navigationEditorBuildNavMeshes();
|
||||
@ -99,7 +114,8 @@ namespace ZL
|
||||
|
||||
|
||||
void setup(const LocationSetup& params);
|
||||
void setupNavigation(const std::string& navigationJsonPath);
|
||||
void setupNavigation(const std::vector<std::string>& paths);
|
||||
bool switchNavigation(int index);
|
||||
InteractiveObject* raycastInteractiveObjects(const Eigen::Vector3f& rayOrigin, const Eigen::Vector3f& rayDir);
|
||||
Character* raycastNpcs(const Eigen::Vector3f& rayOrigin, const Eigen::Vector3f& rayDir, float maxDistance = 100.0f);
|
||||
|
||||
@ -127,6 +143,8 @@ namespace ZL
|
||||
void resolveCharacterCollisions();
|
||||
void updateDynamicReplans(int64_t deltaMs);
|
||||
void loadTeleportZones(const std::string& jsonPath, const char* zipFile);
|
||||
void loadTriggerZones(const std::string& jsonPath, const char* zipFile);
|
||||
void updateTriggerZones(const Eigen::Vector3f& playerPos);
|
||||
|
||||
std::unordered_map<Character*, Eigen::Vector3f> lastCharacterPositions;
|
||||
std::unordered_map<Character*, int64_t> replanCooldownRemainingMs;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "Game.h"
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
#include "Location.h"
|
||||
|
||||
#define SOL_ALL_SAFETIES_ON 1
|
||||
@ -11,6 +12,8 @@ namespace ZL {
|
||||
|
||||
struct ScriptEngine::Impl {
|
||||
sol::state lua;
|
||||
std::unordered_map<std::string, sol::protected_function> triggerEnterCallbacks;
|
||||
std::unordered_map<std::string, sol::protected_function> triggerExitCallbacks;
|
||||
};
|
||||
|
||||
ScriptEngine::ScriptEngine() = default;
|
||||
@ -133,6 +136,24 @@ namespace ZL {
|
||||
}
|
||||
});
|
||||
|
||||
api.set_function("switch_navigation",
|
||||
[game](int index) {
|
||||
if (!game->switchNavigation(index)) {
|
||||
std::cerr << "[script] switch_navigation: index " << index << " out of range\n";
|
||||
}
|
||||
});
|
||||
|
||||
// set_trigger_zone_callbacks(zone_id, on_enter, on_exit)
|
||||
// on_enter and on_exit are optional Lua functions (pass nil to omit).
|
||||
// Called when the player enters or exits the named trigger zone.
|
||||
api.set_function("set_trigger_zone_callbacks",
|
||||
[this_impl = impl.get()](const std::string& zoneId, sol::object onEnter, sol::object onExit) {
|
||||
if (onEnter.is<sol::protected_function>())
|
||||
this_impl->triggerEnterCallbacks[zoneId] = onEnter.as<sol::protected_function>();
|
||||
if (onExit.is<sol::protected_function>())
|
||||
this_impl->triggerExitCallbacks[zoneId] = onExit.as<sol::protected_function>();
|
||||
});
|
||||
|
||||
// receive_npc_gift(npc_index)
|
||||
api.set_function("receive_npc_gift", [game, inventory](int npcIndex) {
|
||||
std::cout << "[script] receive_npc_gift: npc index " << npcIndex << std::endl;
|
||||
@ -254,4 +275,26 @@ namespace ZL {
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::callTriggerEnterCallback(const std::string& zoneId) {
|
||||
if (!impl) return;
|
||||
auto it = impl->triggerEnterCallbacks.find(zoneId);
|
||||
if (it == impl->triggerEnterCallbacks.end()) return;
|
||||
auto result = it->second();
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
std::cerr << "[SCRIPT] trigger enter callback error for '" << zoneId << "': " << err.what() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::callTriggerExitCallback(const std::string& zoneId) {
|
||||
if (!impl) return;
|
||||
auto it = impl->triggerExitCallbacks.find(zoneId);
|
||||
if (it == impl->triggerExitCallbacks.end()) return;
|
||||
auto result = it->second();
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
std::cerr << "[SCRIPT] trigger exit callback error for '" << zoneId << "': " << err.what() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ZL
|
||||
|
||||
@ -24,6 +24,9 @@ public:
|
||||
|
||||
void callNpcInteractCallback(int npcIndex);
|
||||
|
||||
void callTriggerEnterCallback(const std::string& zoneId);
|
||||
void callTriggerExitCallback(const std::string& zoneId);
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
|
||||
@ -11,23 +11,7 @@ bool DialogueSystem::loadDatabase(const std::string& path) {
|
||||
return database.loadFromFile(path);
|
||||
}
|
||||
|
||||
void DialogueSystem::update(int deltaMs, const Eigen::Vector3f& playerPosition) {
|
||||
if (!runtime.isActive()) {
|
||||
for (TriggerZone& zone : triggerZones) {
|
||||
if (zone.once && zone.triggered) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Eigen::Vector3f diff = playerPosition - zone.center;
|
||||
if (diff.norm() <= zone.radius) {
|
||||
if (startDialogue(zone.dialogueId)) {
|
||||
zone.triggered = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DialogueSystem::update(int deltaMs) {
|
||||
runtime.update(deltaMs);
|
||||
overlay.update(runtime.getPresentation(), deltaMs);
|
||||
if (overlay.consumeSkipRequested()) {
|
||||
@ -139,12 +123,4 @@ void DialogueSystem::stopDialogue() {
|
||||
runtime.stop();
|
||||
}
|
||||
|
||||
void DialogueSystem::addTriggerZone(const TriggerZone& zone) {
|
||||
triggerZones.push_back(zone);
|
||||
}
|
||||
|
||||
void DialogueSystem::clearTriggerZones() {
|
||||
triggerZones.clear();
|
||||
}
|
||||
|
||||
} // namespace ZL::Dialogue
|
||||
@ -2,28 +2,17 @@
|
||||
|
||||
#include "dialogue/DialogueOverlay.h"
|
||||
#include "dialogue/DialogueRuntime.h"
|
||||
#include <Eigen/Dense>
|
||||
#include <SDL.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ZL::Dialogue {
|
||||
|
||||
struct TriggerZone {
|
||||
std::string id;
|
||||
std::string dialogueId;
|
||||
Eigen::Vector3f center = Eigen::Vector3f::Zero();
|
||||
float radius = 1.5f;
|
||||
bool once = true;
|
||||
bool triggered = false;
|
||||
};
|
||||
|
||||
class DialogueSystem {
|
||||
public:
|
||||
bool init(Renderer& renderer, const std::string& zipFile = "");
|
||||
bool loadDatabase(const std::string& path);
|
||||
|
||||
void update(int deltaMs, const Eigen::Vector3f& playerPosition);
|
||||
void update(int deltaMs);
|
||||
void draw(Renderer& renderer);
|
||||
|
||||
bool handleKeyDown(SDL_Keycode key);
|
||||
@ -40,14 +29,10 @@ public:
|
||||
void setFlag(const std::string& name, int value) { runtime.setFlag(name, value); }
|
||||
int getFlag(const std::string& name) const { return runtime.getFlag(name); }
|
||||
|
||||
void addTriggerZone(const TriggerZone& zone);
|
||||
void clearTriggerZones();
|
||||
|
||||
private:
|
||||
DialogueDatabase database;
|
||||
DialogueRuntime runtime;
|
||||
DialogueOverlay overlay;
|
||||
std::vector<TriggerZone> triggerZones;
|
||||
};
|
||||
|
||||
} // namespace ZL::Dialogue
|
||||
|
||||
Loading…
Reference in New Issue
Block a user