diff --git a/resources/shaders/default_desktop.fragment b/resources/shaders/default_desktop.fragment index 7548e9e..0012562 100644 --- a/resources/shaders/default_desktop.fragment +++ b/resources/shaders/default_desktop.fragment @@ -1,12 +1,13 @@ //precisionmediump float; uniform sampler2D Texture; +uniform float uAlpha; varying vec2 texCoord; -void main() +void main() { vec4 color = texture2D(Texture,texCoord).rgba; //gl_FragColor = vec4(color.rgb*0.1 + vec3(0.9, 0.9, 0.9), 1.0); - - gl_FragColor = color; - + + gl_FragColor = vec4(color.rgb, color.a * uAlpha); + } \ No newline at end of file diff --git a/resources/shaders/default_web.fragment b/resources/shaders/default_web.fragment index 80c01d7..ce6471c 100644 --- a/resources/shaders/default_web.fragment +++ b/resources/shaders/default_web.fragment @@ -1,12 +1,13 @@ precision mediump float; uniform sampler2D Texture; +uniform float uAlpha; varying vec2 texCoord; -void main() +void main() { vec4 color = texture2D(Texture,texCoord).rgba; //gl_FragColor = vec4(color.rgb*0.1 + vec3(0.9, 0.9, 0.9), 1.0); - - gl_FragColor = color; - + + gl_FragColor = vec4(color.rgb, color.a * uAlpha); + } \ No newline at end of file diff --git a/resources/w/ui/hud_regular.json b/resources/w/ui/hud_regular.json new file mode 100644 index 0000000..76d8faa --- /dev/null +++ b/resources/w/ui/hud_regular.json @@ -0,0 +1,43 @@ +{ + "root": { + "type": "FrameLayout", + "name": "hud_root", + "width": "match_parent", + "height": "match_parent", + "children": [ + { + "type": "LinearLayout", + "orientation": "vertical", + "vertical_align": "center", + "horizontal_align": "center", + "spacing": 0, + "width": "match_parent", + "height": 600, + "children": [ + { + "type": "Button", + "name": "phoneButton", + "width": 229, + "height": 229, + "textures": { + "normal": "resources/w/ui/img/Phone001_State=Default.png", + "hover": "resources/w/ui/img/Phone001_State=Selected.png", + "pressed": "resources/w/ui/img/Phone001_State=Tap.png" + } + }, + { + "type": "Button", + "name": "journalButton", + "width": 229, + "height": 229, + "textures": { + "normal": "resources/w/ui/img/Phone001_State=Default.png", + "hover": "resources/w/ui/img/Phone001_State=Selected.png", + "pressed": "resources/w/ui/img/Phone001_State=Tap.png" + } + } + + ] + }] + } +} diff --git a/resources/w/ui/hud_step0.json b/resources/w/ui/hud_step0.json index 0e32cab..d51150d 100644 --- a/resources/w/ui/hud_step0.json +++ b/resources/w/ui/hud_step0.json @@ -13,6 +13,7 @@ "spacing": 0, "width": "match_parent", "height": 600, + "x" : 300, "children": [ { "type": "StaticImage", @@ -20,7 +21,13 @@ "width": 440, "height": 134, "horizontal_gravity": "center", - "texture": "resources/w/ui/img/Hint2.png" + "texture": "resources/w/ui/img/Hint1.png", + "pulse": { + "minScale": 0.92, + "maxScale": 1.08, + "periodMs": 1500 + }, + "fadeIn": { "durationMs": 600 } }, { "type": "StaticImage", diff --git a/resources/w/ui/hud_step1.json b/resources/w/ui/hud_step1.json index bcbd9db..3890ef7 100644 --- a/resources/w/ui/hud_step1.json +++ b/resources/w/ui/hud_step1.json @@ -5,42 +5,31 @@ "width": "match_parent", "height": "match_parent", "children": [ - { - "type": "TextButton", - "name": "inventory_button", - "x": 50.0, - "y": 50.0, - "width": 150.0, - "height": 60.0, - "text": "Inventory", - "fontSize": 24, - "fontPath": "resources/fonts/DroidSans.ttf", - "textCentered": true, - "color": [1.0, 1.0, 1.0, 1.0], - "textures": { - "normal": "resources/w/red.png", - "hover": "resources/w/red.png", - "pressed": "resources/w/red.png" - } - }, - { - "type": "TextButton", - "name": "quest_journal_button", - "x": 220.0, - "y": 50.0, - "width": 170.0, - "height": 60.0, - "text": "Quests", - "fontSize": 24, - "fontPath": "resources/fonts/DroidSans.ttf", - "textCentered": true, - "color": [1.0, 1.0, 1.0, 1.0], - "textures": { - "normal": "resources/w/red.png", - "hover": "resources/w/red.png", - "pressed": "resources/w/red.png" - } - } - ] + { + "type": "LinearLayout", + "orientation": "vertical", + "vertical_align": "center", + "horizontal_align": "center", + "spacing": 0, + "width": "match_parent", + "height": 600, + "y" : 300, + "children": [ + { + "type": "StaticImage", + "name": "hint2", + "width": 440, + "height": 134, + "horizontal_gravity": "center", + "texture": "resources/w/ui/img/Hint2.png", + "pulse": { + "minScale": 0.92, + "maxScale": 1.08, + "periodMs": 1500 + }, + "fadeIn": { "durationMs": 600 } + } + ] + }] } } diff --git a/resources/w/ui/hud_step2.json b/resources/w/ui/hud_step2.json new file mode 100644 index 0000000..4ead63d --- /dev/null +++ b/resources/w/ui/hud_step2.json @@ -0,0 +1,35 @@ +{ + "root": { + "type": "FrameLayout", + "name": "hud_root", + "width": "match_parent", + "height": "match_parent", + "children": [ + { + "type": "LinearLayout", + "orientation": "vertical", + "vertical_align": "center", + "horizontal_align": "center", + "spacing": 0, + "width": "match_parent", + "height": 600, + "y" : 300, + "children": [ + { + "type": "StaticImage", + "name": "hint3", + "width": 440, + "height": 134, + "horizontal_gravity": "center", + "texture": "resources/w/ui/img/Hint3.png", + "pulse": { + "minScale": 0.92, + "maxScale": 1.08, + "periodMs": 1500 + }, + "fadeIn": { "durationMs": 600 } + } + ] + }] + } +} diff --git a/resources/w/ui/hud_step3.json b/resources/w/ui/hud_step3.json new file mode 100644 index 0000000..2c377a9 --- /dev/null +++ b/resources/w/ui/hud_step3.json @@ -0,0 +1,35 @@ +{ + "root": { + "type": "FrameLayout", + "name": "hud_root", + "width": "match_parent", + "height": "match_parent", + "children": [ + { + "type": "LinearLayout", + "orientation": "vertical", + "vertical_align": "center", + "horizontal_align": "center", + "spacing": 0, + "width": "match_parent", + "height": 600, + "y" : 300, + "children": [ + { + "type": "StaticImage", + "name": "hint4", + "width": 440, + "height": 134, + "horizontal_gravity": "center", + "texture": "resources/w/ui/img/Hint4.png", + "pulse": { + "minScale": 0.92, + "maxScale": 1.08, + "periodMs": 1500 + }, + "fadeIn": { "durationMs": 600 } + } + ] + }] + } +} diff --git a/resources/w/ui/hud_step4.json b/resources/w/ui/hud_step4.json new file mode 100644 index 0000000..2746500 --- /dev/null +++ b/resources/w/ui/hud_step4.json @@ -0,0 +1,35 @@ +{ + "root": { + "type": "FrameLayout", + "name": "hud_root", + "width": "match_parent", + "height": "match_parent", + "children": [ + { + "type": "LinearLayout", + "orientation": "vertical", + "vertical_align": "center", + "horizontal_align": "center", + "spacing": 0, + "width": "match_parent", + "height": 600, + "y" : 300, + "children": [ + { + "type": "StaticImage", + "name": "hint5", + "width": 440, + "height": 134, + "horizontal_gravity": "center", + "texture": "resources/w/ui/img/Hint5.png", + "pulse": { + "minScale": 0.92, + "maxScale": 1.08, + "periodMs": 1500 + }, + "fadeIn": { "durationMs": 600 } + } + ] + }] + } +} diff --git a/resources/w/ui/hud_step5a.json b/resources/w/ui/hud_step5a.json new file mode 100644 index 0000000..b80bad9 --- /dev/null +++ b/resources/w/ui/hud_step5a.json @@ -0,0 +1,57 @@ +{ + "root": { + "type": "FrameLayout", + "name": "hud_root", + "width": "match_parent", + "height": "match_parent", + "children": [ + { + "type": "LinearLayout", + "orientation": "vertical", + "vertical_align": "center", + "horizontal_align": "center", + "spacing": 0, + "width": "match_parent", + "height": 600, + "y" : -250, + "x" : 300, + "children": [ + { + "type": "StaticImage", + "name": "hint6a", + "width": 440, + "height": 134, + "horizontal_gravity": "center", + "texture": "resources/w/ui/img/Hint6a.png", + "pulse": { + "minScale": 0.92, + "maxScale": 1.08, + "periodMs": 1500 + }, + "fadeIn": { + "durationMs": 600 + } + } + ] + }, + { + "type": "Button", + "name": "phoneButton", + "horizontal_gravity": "right", + "vertical_gravity": "top", + "x": -46, + "y" :-46, + "width": 229, + "height": 229, + "clickZoneWidth": 104, + "clickZoneHeight": 104, + "textures": { + "normal": "resources/w/ui/img/Phone001_State=Default.png", + "hover": "resources/w/ui/img/Phone001_State=Selected.png", + "pressed": "resources/w/ui/img/Phone001_State=Tap.png" + } + } + + ] + } +} \ No newline at end of file diff --git a/resources/w/ui/hud_step5aa.json b/resources/w/ui/hud_step5aa.json new file mode 100644 index 0000000..beca2c5 --- /dev/null +++ b/resources/w/ui/hud_step5aa.json @@ -0,0 +1,31 @@ +{ + "root": { + "type": "FrameLayout", + "name": "hud_root", + "width": "match_parent", + "height": "match_parent", + "children": [ + { + "type": "LinearLayout", + "orientation": "vertical", + "vertical_align": "center", + "horizontal_align": "center", + "spacing": 0, + "width": "match_parent", + "height": 600, + "children": [ + { + "type": "Button", + "name": "phoneButton", + "width": 229, + "height": 229, + "textures": { + "normal": "resources/w/ui/img/Phone001_State=Default.png", + "hover": "resources/w/ui/img/Phone001_State=Selected.png", + "pressed": "resources/w/ui/img/Phone001_State=Tap.png" + } + } + ] + }] + } +} diff --git a/resources/w/ui/hud_step5ab.json b/resources/w/ui/hud_step5ab.json new file mode 100644 index 0000000..3999447 --- /dev/null +++ b/resources/w/ui/hud_step5ab.json @@ -0,0 +1,82 @@ +{ + "root": { + "type": "FrameLayout", + "name": "hud_root", + "width": "match_parent", + "height": "match_parent", + "children": [ + { + "type": "LinearLayout", + "orientation": "horizontal", + "vertical_align": "center", + "horizontal_align": "right", + "spacing": 16, + "width": "match_parent", + "height": 600, + "y" : -200, + "children": [ + { + "type": "StaticImage", + "name": "hint6a", + "width": 440, + "height": 134, + "horizontal_gravity": "center", + "texture": "resources/w/ui/img/Hint6a.png", + "pulse": { + "minScale": 0.92, + "maxScale": 1.08, + "periodMs": 1500 + }, + "fadeIn": { "durationMs": 600 } + }, + { + "type": "StaticImage", + "name": "hint6b", + "width": 440, + "height": 134, + "horizontal_gravity": "center", + "texture": "resources/w/ui/img/Hint6b.png", + "pulse": { + "minScale": 0.92, + "maxScale": 1.08, + "periodMs": 1500 + }, + "fadeIn": { "durationMs": 600 } + } + ] + },{ + "type": "Button", + "name": "phoneButton", + "width": 229, + "height": 229, + "x": 74, + "y" :-46, + "clickZoneWidth": 104, + "clickZoneHeight": 104, + "horizontal_gravity": "right", + "vertical_gravity": "top", + "textures": { + "normal": "resources/w/ui/img/Phone001_State=Default.png", + "hover": "resources/w/ui/img/Phone001_State=Selected.png", + "pressed": "resources/w/ui/img/Phone001_State=Tap.png" + } + }, + { + "type": "Button", + "name": "journalButton", + "width": 163, + "height": 163, + "x": -13, + "y" :-13, + "clickZoneWidth": 89, + "clickZoneHeight": 89, + "horizontal_gravity": "right", + "vertical_gravity": "top", + "textures": { + "normal": "resources/w/ui/img/Journal001_State=Default.png", + "hover": "resources/w/ui/img/Journal001_State=Selected.png", + "pressed": "resources/w/ui/img/Journal001_State=Tap.png" + } + }] + } +} diff --git a/resources/w/ui/hud_step5b.json b/resources/w/ui/hud_step5b.json new file mode 100644 index 0000000..d52fb6a --- /dev/null +++ b/resources/w/ui/hud_step5b.json @@ -0,0 +1,54 @@ +{ + "root": { + "type": "FrameLayout", + "name": "hud_root", + "width": "match_parent", + "height": "match_parent", + "children": [ + { + "type": "LinearLayout", + "orientation": "vertical", + "vertical_align": "center", + "horizontal_align": "center", + "spacing": 0, + "width": "match_parent", + "height": 600, + "y" : -250, + "children": [ + { + "type": "StaticImage", + "name": "hint6b", + "width": 440, + "height": 134, + "horizontal_gravity": "center", + "texture": "resources/w/ui/img/Hint6b.png", + "pulse": { + "minScale": 0.92, + "maxScale": 1.08, + "periodMs": 1500 + }, + "fadeIn": { "durationMs": 600 } + } + ] + }, + { + "type": "Button", + "name": "journalButton", + "horizontal_gravity": "right", + "vertical_gravity": "top", + "x": -13, + "y" :-13, + "width": 163, + "height": 163, + "clickZoneWidth": 89, + "clickZoneHeight": 89, + "horizontal_gravity": "right", + "vertical_gravity": "top", + "textures": { + "normal": "resources/w/ui/img/Journal001_State=Default.png", + "hover": "resources/w/ui/img/Journal001_State=Selected.png", + "pressed": "resources/w/ui/img/Journal001_State=Tap.png" + } + }] + } +} diff --git a/resources/w/ui/hud_step5bb.json b/resources/w/ui/hud_step5bb.json new file mode 100644 index 0000000..043e731 --- /dev/null +++ b/resources/w/ui/hud_step5bb.json @@ -0,0 +1,31 @@ +{ + "root": { + "type": "FrameLayout", + "name": "hud_root", + "width": "match_parent", + "height": "match_parent", + "children": [ + { + "type": "LinearLayout", + "orientation": "vertical", + "vertical_align": "center", + "horizontal_align": "center", + "spacing": 0, + "width": "match_parent", + "height": 600, + "children": [ + { + "type": "Button", + "name": "journalButton", + "width": 229, + "height": 229, + "textures": { + "normal": "resources/w/ui/img/Phone001_State=Default.png", + "hover": "resources/w/ui/img/Phone001_State=Selected.png", + "pressed": "resources/w/ui/img/Phone001_State=Tap.png" + } + } + ] + }] + } +} diff --git a/resources/w/ui/img/Hint1.png b/resources/w/ui/img/Hint1.png index 54e7624..5eff0ad 100644 --- a/resources/w/ui/img/Hint1.png +++ b/resources/w/ui/img/Hint1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9df93a2d9772131198ba870d21ec58f2cdad6c8cfddd8d7651d1eb060dc86de2 -size 94084 +oid sha256:58b0cbfdee7f1a9833c2373138fb57b294cd74241eee76d8d6d486bbc1900bba +size 92577 diff --git a/resources/w/ui/img/Hint2.png b/resources/w/ui/img/Hint2.png index 5eff0ad..54e7624 100644 --- a/resources/w/ui/img/Hint2.png +++ b/resources/w/ui/img/Hint2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58b0cbfdee7f1a9833c2373138fb57b294cd74241eee76d8d6d486bbc1900bba -size 92577 +oid sha256:9df93a2d9772131198ba870d21ec58f2cdad6c8cfddd8d7651d1eb060dc86de2 +size 94084 diff --git a/resources/w/ui/img/Hint3.png b/resources/w/ui/img/Hint3.png new file mode 100644 index 0000000..4ccfe79 --- /dev/null +++ b/resources/w/ui/img/Hint3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f538a05f82eddef759a5965eb8ce695f3435377337be4f11c14272a3330f6cf +size 101283 diff --git a/resources/w/ui/img/Hint4.png b/resources/w/ui/img/Hint4.png new file mode 100644 index 0000000..32a2e9f --- /dev/null +++ b/resources/w/ui/img/Hint4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8ec3eed0d8d53878b9509b7208365fd3733d2937736e49954317ed171548382 +size 107965 diff --git a/resources/w/ui/img/Hint5.png b/resources/w/ui/img/Hint5.png new file mode 100644 index 0000000..2fad43f --- /dev/null +++ b/resources/w/ui/img/Hint5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1289f15723d5149051c89f4537d8fe9b2048f22c678b4d7e7385ed63eaf73df +size 90367 diff --git a/resources/w/ui/img/Hint6a.png b/resources/w/ui/img/Hint6a.png new file mode 100644 index 0000000..4a54875 --- /dev/null +++ b/resources/w/ui/img/Hint6a.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00d7779ba5b5188757b79b7a7e96a5ad148ff4a881b4fe0067d288963311985c +size 103833 diff --git a/resources/w/ui/img/Hint6b.png b/resources/w/ui/img/Hint6b.png new file mode 100644 index 0000000..a22a9ef --- /dev/null +++ b/resources/w/ui/img/Hint6b.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e9eefa66da9fd5fd82be7a156d4a34cf3a8cbd2bec67283d056edb34d79a063 +size 141603 diff --git a/resources/w/ui/img/Journal001_State=Default.png b/resources/w/ui/img/Journal001_State=Default.png new file mode 100644 index 0000000..a6eb3ef --- /dev/null +++ b/resources/w/ui/img/Journal001_State=Default.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5548bc89d49799fdd4c5acb60f90ad15e09976707458323a42c5e21beedc080f +size 147743 diff --git a/resources/w/ui/img/Journal001_State=Selected.png b/resources/w/ui/img/Journal001_State=Selected.png new file mode 100644 index 0000000..cd9c2c9 --- /dev/null +++ b/resources/w/ui/img/Journal001_State=Selected.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3420f309c3eef72369229d9316a50e48ecb2a4f34b9999ae907cbcdc3f87465 +size 160455 diff --git a/resources/w/ui/img/Journal001_State=Tap.png b/resources/w/ui/img/Journal001_State=Tap.png new file mode 100644 index 0000000..9dde54e --- /dev/null +++ b/resources/w/ui/img/Journal001_State=Tap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afd82669661fb611bebec0296a9166dfa391b124fc21424f8a821395f1c6dc2a +size 134106 diff --git a/resources/w/ui/img/Phone001_State=Default.png b/resources/w/ui/img/Phone001_State=Default.png new file mode 100644 index 0000000..204b9e2 --- /dev/null +++ b/resources/w/ui/img/Phone001_State=Default.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e1024247cc97777ac6a842487f21082c553e72d6e4ad68bda83b22869096181 +size 194781 diff --git a/resources/w/ui/img/Phone001_State=Selected.png b/resources/w/ui/img/Phone001_State=Selected.png new file mode 100644 index 0000000..f7ee960 --- /dev/null +++ b/resources/w/ui/img/Phone001_State=Selected.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76736f641751a94d09795087d4bdbf1a3463e0cbdc979b649e9d2291f7986b4b +size 238080 diff --git a/resources/w/ui/img/Phone001_State=Tap.png b/resources/w/ui/img/Phone001_State=Tap.png new file mode 100644 index 0000000..949c0d8 --- /dev/null +++ b/resources/w/ui/img/Phone001_State=Tap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:864f06a227a8e679d6dfd3c044b2aed28c0c9c11458230fb91ae1e435db9a406 +size 165128 diff --git a/resources/w/ui/img/PhoneTest001.png b/resources/w/ui/img/PhoneTest001.png new file mode 100644 index 0000000..e0b9f02 --- /dev/null +++ b/resources/w/ui/img/PhoneTest001.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa3d2ea2f920e047dc28dc653d07b62158d4394863c09637c86f8e8a3586e521 +size 1619838 diff --git a/resources/w/ui/img/QuestJournal001.png b/resources/w/ui/img/QuestJournal001.png new file mode 100644 index 0000000..c97ab93 --- /dev/null +++ b/resources/w/ui/img/QuestJournal001.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa4827b369c3e2ad8add0c1b99663da2fedc4f923bd1cab75e27446e0b13286f +size 419160 diff --git a/resources/w/ui/screen_journal.json b/resources/w/ui/screen_journal.json new file mode 100644 index 0000000..0b0ea0a --- /dev/null +++ b/resources/w/ui/screen_journal.json @@ -0,0 +1,25 @@ +{ + "root": { + "type": "FrameLayout", + "name": "hud_root", + "width": "match_parent", + "height": "match_parent", + "vertical_align": "center", + "horizontal_align": "center", + "children": [ + { + "type": "Button", + "name": "journalExitButton", + "horizontal_gravity": "center", + "vertical_gravity": "center", + "width": 1125, + "height": 520, + "textures": { + "normal": "resources/w/ui/img/QuestJournal001.png", + "hover": "resources/w/ui/img/QuestJournal001.png", + "pressed": "resources/w/ui/img/QuestJournal001.png" + } + } + ] + } +} \ No newline at end of file diff --git a/resources/w/ui/screen_phone.json b/resources/w/ui/screen_phone.json new file mode 100644 index 0000000..4c09d40 --- /dev/null +++ b/resources/w/ui/screen_phone.json @@ -0,0 +1,25 @@ +{ + "root": { + "type": "FrameLayout", + "name": "hud_root", + "width": "match_parent", + "height": "match_parent", + "vertical_align": "center", + "horizontal_align": "center", + "children": [ + { + "type": "Button", + "name": "phoneExitButton", + "horizontal_gravity": "center", + "vertical_gravity": "center", + "width": 1232, + "height": 627, + "textures": { + "normal": "resources/w/ui/img/PhoneTest001.png", + "hover": "resources/w/ui/img/PhoneTest001.png", + "pressed": "resources/w/ui/img/PhoneTest001.png" + } + } + ] + } +} \ No newline at end of file diff --git a/src/Environment.h b/src/Environment.h index 4293b60..10f18cd 100644 --- a/src/Environment.h +++ b/src/Environment.h @@ -15,7 +15,7 @@ namespace ZL { using std::max; #endif - constexpr float DEFAULT_ZOOM = 24.f; + constexpr float DEFAULT_ZOOM = 6.f; class Environment { public: diff --git a/src/Game.cpp b/src/Game.cpp index 603c46d..39e7057 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -369,6 +369,24 @@ namespace ZL locations["uni_interior"]->onTeleport = teleportCallback; locations["location_dorm"]->onTeleport = teleportCallback; + // Wire tutorial advance callbacks for all locations. + // advanceTutorialStep() guards against double-advancing, so sharing is safe. + for (auto& [name, loc] : locations) { + loc->dialogueSystem.setOnDialogueAdvanced([this]() { + menuManager.advanceTutorialStep(); + }); + loc->onPlayerFloorWalk = [this]() { + if (menuManager.tutorialStep == TutorialStep::Step2) { + menuManager.advanceTutorialStep(); + } + }; + } + + // Wire inventory item-pickup callback for tutorial step4/5 item tracking. + inventory.onItemAdded = [this](const std::string& itemId) { + menuManager.onItemPickedUp(itemId); + }; + currentLocation = locations["location_dorm"]; currentLocation->scriptEngine.callLocationEnterCallback(); @@ -552,6 +570,8 @@ namespace ZL updateDarklandsFlash(delta); + menuManager.uiManager.update(static_cast(delta)); + if (currentLocation) { currentLocation->update(delta); @@ -661,6 +681,10 @@ namespace ZL if (Environment::zoom < zoomstep) { Environment::zoom = zoomstep; } + // Tutorial step3 → step4: any mouse-wheel scroll counts as "zoom gesture". + if (menuManager.tutorialStep == TutorialStep::Step3) { + menuManager.advanceTutorialStep(); + } } if (event.type == SDL_KEYDOWN && event.key.repeat == 0) { @@ -722,8 +746,10 @@ namespace ZL break; case SDLK_l: - x = x - 1; - std::cout << "current x: " << x << std::endl; + //x = x - 1; + //std::cout << "current x: " << x << std::endl; + std::cout << "Azimuth: " << currentLocation->cameraAzimuth << std::endl; + std::cout << "Inclination: " << currentLocation->cameraInclination << std::endl; break; case SDLK_c: @@ -826,6 +852,10 @@ namespace ZL // movement threshold was crossed. currentLocation->lastMouseX = eventX; currentLocation->lastMouseY = eventY; + + // Snapshot current angles so we can measure how far the user rotates. + dragStartAzimuth = currentLocation->cameraAzimuth; + dragStartInclination = currentLocation->cameraInclination; } } @@ -881,6 +911,13 @@ namespace ZL static const float zoomMin = 2.0f; if (newZoom < zoomMin) newZoom = zoomMin; Environment::zoom = newZoom; + + // Tutorial step3 → step4: detect a significant pinch-zoom (≥ 2 zoom units). + if (menuManager.tutorialStep == TutorialStep::Step3) { + if (std::abs(Environment::zoom - pinchStartZoom) >= 2.0f) { + menuManager.advanceTutorialStep(); + } + } } void Game::endPinch() @@ -1004,6 +1041,19 @@ namespace ZL if (currentLocation) { // Forwarded for dialogue hover and (when cameraDragging) camera rotation. currentLocation->handleMotion(fingerId, eventX, eventY, mx, my); + + // Tutorial step1 → step2: detect a significant camera rotation on BOTH axes. + // ~0.15 rad (≈8.6°) per axis ensures the user intentionally panned in 2D, + // not just nudged a single axis by accident. + static constexpr float TUTORIAL_ROTATION_THRESHOLD = 0.15f; + if (cameraDragging + && menuManager.tutorialStep == TutorialStep::Step1) { + float deltaAz = std::abs(currentLocation->cameraAzimuth - dragStartAzimuth); + float deltaInc = std::abs(currentLocation->cameraInclination - dragStartInclination); + if (deltaAz >= TUTORIAL_ROTATION_THRESHOLD && deltaInc >= TUTORIAL_ROTATION_THRESHOLD) { + menuManager.advanceTutorialStep(); + } + } } } diff --git a/src/Game.h b/src/Game.h index aa6a0ad..b919052 100644 --- a/src/Game.h +++ b/src/Game.h @@ -87,6 +87,11 @@ namespace ZL { float pinchStartDistance = 0.0f; float pinchStartZoom = 0.0f; + // Tutorial: azimuth and inclination captured at the start of each camera drag, + // used to measure how far the user has rotated before advancing the tutorial step. + float dragStartAzimuth = 0.0f; + float dragStartInclination = 0.0f; + std::unique_ptr audioPlayer; int64_t getSyncTimeMs(); diff --git a/src/Location.cpp b/src/Location.cpp index 5db9b8d..7137f0e 100644 --- a/src/Location.cpp +++ b/src/Location.cpp @@ -1519,6 +1519,7 @@ namespace ZL targetInteractNpc = nullptr; targetInteractNpcIndex = -1; targetTeleportZone = nullptr; + if (onPlayerFloorWalk) onPlayerFloorWalk(); } } else { diff --git a/src/Location.h b/src/Location.h index 7abe3fe..960ab66 100644 --- a/src/Location.h +++ b/src/Location.h @@ -51,12 +51,11 @@ namespace ZL std::vector interactiveObjects; - std::unique_ptr player; std::vector> npcs; - float cameraAzimuth = 0.0f; - float cameraInclination = M_PI * 30.f / 180.f; + float cameraAzimuth = -2.35; + float cameraInclination = 1.1036;//M_PI * 30.f / 180.f; std::vector navigationMaps; PathFinder* navigation = nullptr; @@ -87,6 +86,10 @@ namespace ZL // Read by draw functions and raycast — do not write from Location code. bool isDarklands = false; + // Called when the player successfully taps the ground and a floor walk target is set. + // Used by the tutorial system to detect the "tap to walk" gesture. + std::function onPlayerFloorWalk; + // Set by Game after setup(). Lua and onDeathAnimComplete call this to // request the transition without coupling Location to Game directly. std::function requestDarklandsTransition; diff --git a/src/MenuManager.cpp b/src/MenuManager.cpp index 69167fd..b52beae 100644 --- a/src/MenuManager.cpp +++ b/src/MenuManager.cpp @@ -34,7 +34,16 @@ namespace ZL { inventory = &inv; //hudRoot = loadUiFromFile("resources/config2/hud.json", renderer, zipFile); - hudRoot = loadUiFromFile("resources/w/ui/hud_step0.json", renderer, zipFile); + hudRoot = loadUiFromFile("resources/w/ui/hud_step0.json", renderer, zipFile); + hudStep1Root = loadUiFromFile("resources/w/ui/hud_step1.json", renderer, zipFile); + hudStep2Root = loadUiFromFile("resources/w/ui/hud_step2.json", renderer, zipFile); + hudStep3Root = loadUiFromFile("resources/w/ui/hud_step3.json", renderer, zipFile); + hudStep4Root = loadUiFromFile("resources/w/ui/hud_step4.json", renderer, zipFile); + hudStep5aRoot = loadUiFromFile("resources/w/ui/hud_step5a.json", renderer, zipFile); + hudStep5bRoot = loadUiFromFile("resources/w/ui/hud_step5b.json", renderer, zipFile); + hudStep5abRoot = loadUiFromFile("resources/w/ui/hud_step5ab.json", renderer, zipFile); + phoneScreenRoot = loadUiFromFile("resources/w/ui/screen_phone.json", renderer, zipFile); + journalScreenRoot= loadUiFromFile("resources/w/ui/screen_journal.json", renderer, zipFile); inventoryRoot = loadUiFromFile("resources/config2/ui_inventory.json", renderer, zipFile); questJournalRoot = loadUiFromFile("resources/config2/ui_quest_journal.json", renderer, zipFile); @@ -124,6 +133,119 @@ namespace ZL { } } + void MenuManager::openPhoneScreen() { + state = GameState::PhoneScreen; + tutorialPhoneScreenOpened = true; + // Hide the phone hint on the current HUD so it stays hidden when we return. + uiManager.setNodeVisible("hint6a", false); + uiManager.pushMenuFromSavedRoot(phoneScreenRoot); + uiManager.setButtonCallback("phoneExitButton", [this](const std::string&) { + closePhoneScreen(); + }); + } + + void MenuManager::closePhoneScreen() { + state = GameState::Gameplay; + uiManager.popMenu(); + } + + void MenuManager::openJournalScreen() { + state = GameState::JournalScreen; + tutorialJournalScreenOpened = true; + // Hide the journal hint on the current HUD so it stays hidden when we return. + uiManager.setNodeVisible("hint6b", false); + uiManager.pushMenuFromSavedRoot(journalScreenRoot); + uiManager.setButtonCallback("journalExitButton", [this](const std::string&) { + closeJournalScreen(); + }); + } + + void MenuManager::closeJournalScreen() { + state = GameState::Gameplay; + uiManager.popMenu(); + } + + // Registers phoneButton / journalButton callbacks on the current HUD root + // and hides any hints that have already been completed. + // Called after every replaceRoot during step 5. + void MenuManager::setupStep5Callbacks() { + if (uiManager.findButton("phoneButton")) { + uiManager.setButtonCallback("phoneButton", [this](const std::string&) { + openPhoneScreen(); + }); + } + if (uiManager.findButton("journalButton")) { + uiManager.setButtonCallback("journalButton", [this](const std::string&) { + openJournalScreen(); + }); + } + if (tutorialPhoneScreenOpened) uiManager.setNodeVisible("hint6a", false); + if (tutorialJournalScreenOpened) uiManager.setNodeVisible("hint6b", false); + } + + void MenuManager::advanceTutorialStep() { + std::shared_ptr nextRoot; + + switch (tutorialStep) { + case TutorialStep::Step0: + tutorialStep = TutorialStep::Step1; + nextRoot = hudStep1Root; + break; + case TutorialStep::Step1: + tutorialStep = TutorialStep::Step2; + nextRoot = hudStep2Root; + break; + case TutorialStep::Step2: + tutorialStep = TutorialStep::Step3; + nextRoot = hudStep3Root; + break; + case TutorialStep::Step3: + tutorialStep = TutorialStep::Step4; + nextRoot = hudStep4Root; + break; + default: + return; // Step4/Step5 transitions are driven by onItemPickedUp + } + + if (state == GameState::Gameplay && nextRoot) { + uiManager.replaceRoot(nextRoot); + } + } + + void MenuManager::onItemPickedUp(const std::string& itemId) { + if (tutorialStep != TutorialStep::Step4 && tutorialStep != TutorialStep::Step5) { + return; + } + + if (itemId == "phone") tutorialPhonePickedUp = true; + if (itemId == "journal") tutorialJournalPickedUp = true; + + if (tutorialStep == TutorialStep::Step4) { + tutorialStep = TutorialStep::Step5; + } + + refreshItemPickupHud(); + } + + void MenuManager::refreshItemPickupHud() { + if (state != GameState::Gameplay) return; + + std::shared_ptr nextRoot; + if (tutorialPhonePickedUp && tutorialJournalPickedUp) { + nextRoot = hudStep5abRoot; + } else if (tutorialPhonePickedUp) { + nextRoot = hudStep5aRoot; + } else if (tutorialJournalPickedUp) { + nextRoot = hudStep5bRoot; + } + + if (nextRoot) { + uiManager.replaceRoot(nextRoot); + // Register item-screen buttons and re-apply any already-completed hint visibility. + setupStep5Callbacks(); + } + } + void MenuManager::refreshQuestJournalUi() { visibleQuestIds.clear(); auto quests = questJournal.getVisibleQuests(); diff --git a/src/MenuManager.h b/src/MenuManager.h index 2f1591c..826a6b6 100644 --- a/src/MenuManager.h +++ b/src/MenuManager.h @@ -16,7 +16,18 @@ namespace ZL { enum class GameState { Gameplay, Inventory, - QuestJournal + QuestJournal, + PhoneScreen, + JournalScreen + }; + + enum class TutorialStep { + Step0, // Dialogue hint: "click to advance" + Step1, // Camera rotation hint + Step2, // Floor tap / walk hint + Step3, // Pinch-zoom hint + Step4, // Pick-up item hint + Step5, // Post-pickup reaction (sub-state: which items were collected) }; class MenuManager { @@ -38,6 +49,16 @@ namespace ZL { bool isInventoryOpen() const { return state == GameState::Inventory; } bool isQuestJournalOpen() const { return state == GameState::QuestJournal; } + void openPhoneScreen(); + void closePhoneScreen(); + void openJournalScreen(); + void closeJournalScreen(); + + void advanceTutorialStep(); + void onItemPickedUp(const std::string& itemId); + + TutorialStep tutorialStep = TutorialStep::Step0; + protected: Renderer& renderer; @@ -45,11 +66,27 @@ namespace ZL { void enterGameplay(); void refreshQuestJournalUi(); void selectQuestByIndex(int index); + void refreshItemPickupHud(); + void setupStep5Callbacks(); GameState state = GameState::Gameplay; Inventory* inventory = nullptr; + bool tutorialPhonePickedUp = false; + bool tutorialJournalPickedUp = false; + bool tutorialPhoneScreenOpened = false; + bool tutorialJournalScreenOpened = false; + std::shared_ptr hudRoot; + std::shared_ptr hudStep1Root; + std::shared_ptr hudStep2Root; + std::shared_ptr hudStep3Root; + std::shared_ptr hudStep4Root; + std::shared_ptr hudStep5aRoot; + std::shared_ptr hudStep5bRoot; + std::shared_ptr hudStep5abRoot; + std::shared_ptr phoneScreenRoot; + std::shared_ptr journalScreenRoot; std::shared_ptr inventoryRoot; std::shared_ptr questJournalRoot; diff --git a/src/UiManager.cpp b/src/UiManager.cpp index fc169a3..b48c8a2 100644 --- a/src/UiManager.cpp +++ b/src/UiManager.cpp @@ -373,9 +373,17 @@ namespace ZL { void UiStaticImage::draw(Renderer& renderer) const { if (!texture) return; + const float alpha = (fadeInEnabled && fadeInDurationMs > 0.0f) + ? std::clamp(fadeInElapsedMs / fadeInDurationMs, 0.0f, 1.0f) + : 1.0f; + renderer.RenderUniform1i(textureUniformName, 0); + renderer.RenderUniform1f("uAlpha", alpha); glBindTexture(GL_TEXTURE_2D, texture->getTexID()); renderer.DrawVertexRenderStruct(mesh); + if (alpha < 1.0f) { + renderer.RenderUniform1f("uAlpha", 1.0f); // restore for subsequent draws + } } void UiTextField::draw(Renderer& renderer) const { @@ -504,6 +512,8 @@ namespace ZL { btn->texDisabled = loadTex("disabled"); btn->border = j.value("border", 0.0f); + if (j.contains("clickZoneWidth")) btn->clickZoneWidth = j["clickZoneWidth"].get(); + if (j.contains("clickZoneHeight")) btn->clickZoneHeight = j["clickZoneHeight"].get(); node->button = btn; } @@ -616,6 +626,8 @@ namespace ZL { if (j.contains("color") && j["color"].is_array() && j["color"].size() == 4) { for (int i = 0; i < 4; ++i) tb->color[i] = j["color"][i].get(); } + if (j.contains("clickZoneWidth")) tb->clickZoneWidth = j["clickZoneWidth"].get(); + if (j.contains("clickZoneHeight")) tb->clickZoneHeight = j["clickZoneHeight"].get(); tb->textRenderer = std::make_unique(); if (!tb->textRenderer->init(renderer, tb->fontPath, tb->fontSize, zipFile)) { @@ -679,6 +691,23 @@ namespace ZL { } node->staticImage = img; + + // Optional fade-in on display + if (j.contains("fadeIn") && j["fadeIn"].is_object()) { + const auto& fi = j["fadeIn"]; + img->fadeInEnabled = true; + img->fadeInDurationMs = fi.value("durationMs", 1000.0f); + img->fadeInElapsedMs = 0.0f; + } + + // Optional pulse-scale animation + if (j.contains("pulse") && j["pulse"].is_object()) { + const auto& p = j["pulse"]; + node->pulseEnabled = true; + node->pulseMinScale = p.value("minScale", 0.9f); + node->pulseMaxScale = p.value("maxScale", 1.1f); + node->pulsePeriodMs = p.value("periodMs", 1000.0f); + } } if (typeStr == "TextView") { @@ -777,6 +806,7 @@ namespace ZL { textViews.clear(); textFields.clear(); staticImages.clear(); + pulsingNodes.clear(); collectButtonsAndSliders(root); nodeActiveAnims.clear(); @@ -1020,6 +1050,12 @@ namespace ZL { } if (node->staticImage) { staticImages.push_back(node->staticImage); + if (node->staticImage->fadeInEnabled) { + node->staticImage->fadeInElapsedMs = 0.0f; // restart fade every time UI is shown + } + } + if (node->pulseEnabled && node->staticImage) { + pulsingNodes.push_back(node); } for (auto& c : node->children) collectButtonsAndSliders(c); } @@ -1128,6 +1164,7 @@ namespace ZL { prev.textViews = textViews; prev.textFields = textFields; prev.staticImages = staticImages; + prev.pulsingNodes = pulsingNodes; prev.pressedButtons = pressedButtons; prev.pressedTextButtons = pressedTextButtons; prev.pressedSliders = pressedSliders; @@ -1190,6 +1227,7 @@ namespace ZL { textViews = s.textViews; textFields = s.textFields; staticImages = s.staticImages; + pulsingNodes = s.pulsingNodes; pressedButtons = s.pressedButtons; pressedTextButtons = s.pressedTextButtons; pressedSliders = s.pressedSliders; @@ -1233,6 +1271,7 @@ namespace ZL { renderer.PushProjectionMatrix(Environment::projectionWidth, Environment::projectionHeight, -1, 1); renderer.PushMatrix(); renderer.LoadIdentity(); + renderer.RenderUniform1f("uAlpha", 1.0f); // ensure alpha is fully opaque unless a widget overrides it std::function&)> drawNode = [&](const std::shared_ptr& node) { @@ -1301,6 +1340,29 @@ namespace ZL { void UiManager::update(float deltaMs) { if (!root) return; + // Fade-in animations (StaticImage elements with fadeInEnabled == true) + for (auto& img : staticImages) { + if (!img || !img->fadeInEnabled) continue; + if (img->fadeInElapsedMs < img->fadeInDurationMs) { + img->fadeInElapsedMs += deltaMs; + if (img->fadeInElapsedMs > img->fadeInDurationMs) + img->fadeInElapsedMs = img->fadeInDurationMs; + } + } + + // Pulse-scale animations (StaticImage nodes with pulseEnabled == true) + for (auto& node : pulsingNodes) { + if (!node) continue; + node->pulseElapsedMs += deltaMs; + if (node->pulseElapsedMs >= node->pulsePeriodMs) + node->pulseElapsedMs = std::fmod(node->pulseElapsedMs, node->pulsePeriodMs); + const float phase = node->pulseElapsedMs / node->pulsePeriodMs; + const float t = (std::sin(phase * 2.0f * static_cast(M_PI)) + 1.0f) * 0.5f; + const float s = node->pulseMinScale + (node->pulseMaxScale - node->pulseMinScale) * t; + node->scaleX = s; + node->scaleY = s; + } + std::vector, size_t>> animationsToRemove; std::vector> pendingCallbacks; @@ -1490,7 +1552,7 @@ namespace ZL { for (auto& b : buttons) { if (b->state != ButtonState::Disabled) { - if (b->rect.containsConsideringBorder((float)x, (float)y, b->border)) { + if (b->getClickZoneRect().containsConsideringBorder((float)x, (float)y, b->border)) { if (b->state != ButtonState::Pressed) b->state = ButtonState::Hover; } else { @@ -1501,7 +1563,7 @@ namespace ZL { for (auto& tb : textButtons) { if (tb->state != ButtonState::Disabled) { - if (tb->rect.containsConsideringBorder((float)x, (float)y, tb->border)) { + if (tb->getClickZoneRect().containsConsideringBorder((float)x, (float)y, tb->border)) { if (tb->state != ButtonState::Pressed) tb->state = ButtonState::Hover; } else { @@ -1534,7 +1596,7 @@ namespace ZL { for (auto& b : buttons) { if (b->state != ButtonState::Disabled) { - if (b->rect.containsConsideringBorder((float)x, (float)y, b->border)) { + if (b->getClickZoneRect().containsConsideringBorder((float)x, (float)y, b->border)) { b->state = ButtonState::Pressed; pressedButtons[fingerId] = b; if (b->onPress) b->onPress(b->name); @@ -1546,7 +1608,7 @@ namespace ZL { for (auto& tb : textButtons) { if (tb->state != ButtonState::Disabled) { - if (tb->rect.containsConsideringBorder((float)x, (float)y, tb->border)) { + if (tb->getClickZoneRect().containsConsideringBorder((float)x, (float)y, tb->border)) { tb->state = ButtonState::Pressed; pressedTextButtons[fingerId] = tb; if (tb->onPress) tb->onPress(tb->name); @@ -1593,7 +1655,7 @@ namespace ZL { if (btnIt != pressedButtons.end()) { auto b = btnIt->second; if (b) { - bool contains = b->rect.contains((float)x, (float)y); + bool contains = b->getClickZoneRect().contains((float)x, (float)y); if (b->state == ButtonState::Pressed) { if (contains) { clicked.push_back(b); @@ -1609,7 +1671,7 @@ namespace ZL { if (tbIt != pressedTextButtons.end()) { auto tb = tbIt->second; if (tb) { - bool contains = tb->rect.contains((float)x, (float)y); + bool contains = tb->getClickZoneRect().contains((float)x, (float)y); if (tb->state == ButtonState::Pressed) { if (contains) { clickedText.push_back(tb); diff --git a/src/UiManager.h b/src/UiManager.h index 1246249..6d8e84f 100644 --- a/src/UiManager.h +++ b/src/UiManager.h @@ -93,6 +93,17 @@ namespace ZL { VertexRenderStruct mesh; + // Optional explicit hit-test zone, centred on rect. + // 0 means "use rect.w / rect.h" (default behaviour). + float clickZoneWidth = 0.0f; + float clickZoneHeight = 0.0f; + + UiRect getClickZoneRect() const { + float cw = (clickZoneWidth > 0.0f) ? clickZoneWidth : rect.w; + float ch = (clickZoneHeight > 0.0f) ? clickZoneHeight : rect.h; + return { rect.x + (rect.w - cw) * 0.5f, rect.y + (rect.h - ch) * 0.5f, cw, ch }; + } + std::function onClick; std::function onPress; // fires on touch/mouse down @@ -139,6 +150,17 @@ namespace ZL { ButtonState state = ButtonState::Normal; VertexRenderStruct mesh; + // Optional explicit hit-test zone, centred on rect. + // 0 means "use rect.w / rect.h" (default behaviour). + float clickZoneWidth = 0.0f; + float clickZoneHeight = 0.0f; + + UiRect getClickZoneRect() const { + float cw = (clickZoneWidth > 0.0f) ? clickZoneWidth : rect.w; + float ch = (clickZoneHeight > 0.0f) ? clickZoneHeight : rect.h; + return { rect.x + (rect.w - cw) * 0.5f, rect.y + (rect.h - ch) * 0.5f, cw, ch }; + } + // Text drawn on top of the button std::string text; std::string fontPath = "resources/fonts/DroidSans.ttf"; @@ -209,6 +231,11 @@ namespace ZL { VertexRenderStruct mesh; + // Fade-in on first display (triggers each time the containing UI is shown) + bool fadeInEnabled = false; + float fadeInDurationMs = 1000.0f; + float fadeInElapsedMs = 0.0f; // runtime, reset by collectButtonsAndSliders + void buildMesh(); void draw(Renderer& renderer) const; }; @@ -236,6 +263,13 @@ namespace ZL { bool visible = true; + // Pulse-scale animation (StaticImage only; auto-starts when pulseEnabled == true) + bool pulseEnabled = false; + float pulseMinScale = 1.0f; + float pulseMaxScale = 1.1f; + float pulsePeriodMs = 1000.0f; + float pulseElapsedMs = 0.0f; // runtime, not persisted in JSON + // Иерархия std::vector> children; @@ -322,6 +356,13 @@ namespace ZL { tb->animScaleY = 1.0f; } } + for (auto& n : pulsingNodes) { + if (n) { + n->scaleX = 1.0f; + n->scaleY = 1.0f; + n->pulseElapsedMs = 0.0f; + } + } } std::shared_ptr findButton(const std::string& name); @@ -404,6 +445,7 @@ namespace ZL { std::vector> textViews; std::vector> textFields; std::vector> staticImages; + std::vector> pulsingNodes; std::map, std::vector> nodeActiveAnims; std::map, std::function> animCallbacks; // key: (nodeName, animName) @@ -422,6 +464,7 @@ namespace ZL { std::vector> textViews; std::vector> textFields; std::vector> staticImages; + std::vector> pulsingNodes; std::map> pressedButtons; std::map> pressedTextButtons; std::map> pressedSliders; diff --git a/src/dialogue/DialogueSystem.cpp b/src/dialogue/DialogueSystem.cpp index 2688739..435da0b 100644 --- a/src/dialogue/DialogueSystem.cpp +++ b/src/dialogue/DialogueSystem.cpp @@ -104,6 +104,7 @@ bool DialogueSystem::handlePointerReleased(float x, float y) { if (advanceDialogue) { runtime.confirmAdvance(); + if (onDialogueAdvancedCallback) onDialogueAdvancedCallback(); return true; } @@ -143,4 +144,8 @@ void DialogueSystem::stopDialogue() { runtime.stop(); } +void DialogueSystem::setOnDialogueAdvanced(std::function cb) { + onDialogueAdvancedCallback = std::move(cb); +} + } // namespace ZL::Dialogue \ No newline at end of file diff --git a/src/dialogue/DialogueSystem.h b/src/dialogue/DialogueSystem.h index 91ecd90..0021d71 100644 --- a/src/dialogue/DialogueSystem.h +++ b/src/dialogue/DialogueSystem.h @@ -27,6 +27,7 @@ public: void setOnDialogueLineStarted(std::function cb); void setOnCutsceneLineStarted(std::function cb); void setOnCutsceneFadeInComplete(std::function cb); + void setOnDialogueAdvanced(std::function cb); void stopDialogue(); bool isActive() const { return runtime.isActive(); } @@ -39,6 +40,7 @@ private: DialogueDatabase database; DialogueRuntime runtime; DialogueOverlay overlay; + std::function onDialogueAdvancedCallback; }; } // namespace ZL::Dialogue diff --git a/src/items/Item.cpp b/src/items/Item.cpp index b8b12eb..07d1943 100644 --- a/src/items/Item.cpp +++ b/src/items/Item.cpp @@ -7,6 +7,7 @@ namespace ZL { void Inventory::addItem(const Item& item) { items.push_back(item); std::cout << "Item added to inventory: " << item.name << std::endl; + if (onItemAdded) onItemAdded(item.id); } void Inventory::removeItem(const std::string& itemId) { diff --git a/src/items/Item.h b/src/items/Item.h index cf27f4f..68a2c1c 100644 --- a/src/items/Item.h +++ b/src/items/Item.h @@ -2,6 +2,7 @@ #include #include #include +#include namespace ZL { @@ -28,6 +29,9 @@ namespace ZL { bool hasItem(const std::string& itemId) const; void clear() { items.clear(); } size_t getCount() const { return items.size(); } + + // Called whenever an item is added; receives the item id. + std::function onItemAdded; }; } // namespace ZL \ No newline at end of file