function foo() tree() .node("p1", Quaternion(), Vector3(0, 0, -200)) .entity("b1", "residental-house1.glb") .endnode() .node("p2", Quaternion(), Vector3(0, 0, -150)) .entity("residental-house1.glb") .endnode() .node("p3", Quaternion(), Vector3(0, 0, -100)) .entity("residental-house1.glb") .endnode() .node("p4", Quaternion(), Vector3(0, 0, -50)) .entity("residental-house1.glb") .endnode() .node("p5", Quaternion(), Vector3(0, 0, 50)) .entity("residental-house1.glb") .endnode() .node("p6", Quaternion(), Vector3(0, 0, 100)) .entity("residental-house1.glb") .endnode() .node("p7", Quaternion(), Vector3(0, 0, 150)) .entity("residental-house2.glb") .endnode() .node("p8", Quaternion(), Vector3(0, 0, 200)) .entity("residental-house3.glb") .endnode() for x = -1000, 1000, 50 do for z = -1000, 1000, 50 do if not ((x >-100 and x < 100) and (z > -100 and z < 100)) then tree() .node("p00" .. tostring(x * 1000 + z), Quaternion(), Vector3(x, 0, z)) .entity("residental-house2.glb") .endnode() end end end v = Vector3(0, 1, 2) end --[[ narration = { position = 1, narration_start = { "The party was hot, girls were sexy the wine, beer and whisky were in \ enormous numbers. It was anniversary since you set sail with your friends. \ The sea was calm and everything promised you another great night.", "The whole year with your friends on your ship over vast seas of the world in decay was almost over.\ It was so good year full of adventure, romance, indecency and luxury.", "Your trusted friends decided that you have too much, they have too much of you and you owe them a lot.", "They found you drunk in your room and moved to the deck and used ropes to \ restrain you and attach a bucket of stones or something else heavy to your body.", "After a few hours passed two strong people pulled you to the side and \ dropped you into the sea. Last thing you heard before you hit the water was happy laugher..." }, progress = function(this) if #this.narration_start < this.position then return "" end local ret = this.narration_start[this.position] this.position = this.position + 1 return ret end, } ]]-- local narrator = require('narrator.narrator') function dump(o) if type(o) == 'table' then local s = '{ ' for k,v in pairs(o) do if type(k) ~= 'number' then k = '"'..k..'"' end s = s .. '['..k..'] = ' .. dump(v) .. ',' end return s .. '} ' else return tostring(o) end end --[[ function _narration() local ret = "" local choices = {} if story:can_continue() then print("can continue") local paragraph = story:continue(1) print(dump(paragraph)) local text = paragraph.text if paragraph.tags then text = text .. ' #' .. table.concat(paragraph.tags, ' #') for i, tag in ipairs(paragraph.tags) do if tag == "mc_is_free" then ecs_character_set("player", "gravity", true) ecs_character_set("player", "buoyancy", true) end end end ret = text if story:can_choose() then local ch = story:get_choices() for i, choice in ipairs(ch) do table.insert(choices, choice.text) print(i, dump(choice)) end if #choices == 1 and choices[1] == "Ascend" then story:choose(1) choices = {} end if #choices == 1 and choices[1] == "Continue" then story:choose(1) choices = {} end end else print("can NOT continue") end print(ret) if (#choices > 0) then print("choices!!!") narrate(ret, choices) else narrate(ret) end end ]]-- function Quest(name, book) local quest = { name = name, active = false, activate = function(this) this.active = true this.story:begin() this:_narration() end, event = function(this, event, event_data) if not this.active then return end if event == "narration_progress" then print(" in progress...") this:_narration() elseif event == "narration_answered" then local answer = narration_get_answer() this.story:choose(answer) print("answered:", answer) this:_narration() end end, _handle_tag = function(this, tag) if tag == "mc_is_free" then ecs_character_set("player", "gravity", true) ecs_character_set("player", "buoyancy", true) end end, _narration = function(this) local ret = "" local choices = {} local have_choice = false local have_paragraph = false if not this.active then print("not active") return end if this.story:can_continue() then print("can continue") have_paragraph = true local paragraph = this.story:continue(1) print(dump(paragraph)) local text = paragraph.text if paragraph.tags then text = text .. ' #' .. table.concat(paragraph.tags, ' #') for i, tag in ipairs(paragraph.tags) do this:_handle_tag(tag) end end ret = text if this.story:can_choose() then have_choice = true local ch = this.story:get_choices() for i, choice in ipairs(ch) do table.insert(choices, choice.text) print(i, dump(choice)) end if #choices == 1 and choices[1] == "Ascend" then this.story:choose(1) choices = {} end if #choices == 1 and choices[1] == "Continue" then this.story:choose(1) choices = {} end end else print("can NOT continue") end print(ret) if (#choices > 0) then print("choices!!!") narrate(ret, choices) else narrate(ret) end if not have_choice and not have_paragraph then this:complete() this.active = false else print("can continue") end end, complete = function(this) print(this.name .. 'complete') end, story = narrator.init_story(book) } -- Begin the story return quest end function StartGameQuest() -- Parse a book from the Ink file. local book = narrator.parse_file('stories.initiation') local quest = Quest('start game', book) quest.base = {} quest.base.activate = quest.activate quest.base.complete = quest.complete quest.boat = false quest.activate = function(this) print('activate...') local mc_is_free = function() this.boat = true local ent = ecs_get_player_entity() ecs_character("params-set", ent, "gravity", true) ecs_character("params-set", ent, "buoyancy", true) end this.story:bind('mc_is_free', mc_is_free) this.base.activate(this) end quest.complete = function(this) this.base.complete(this) this.active = false if not this.boat then ecs_save_object_debug(boat, 'boat.scene') end end return quest end function BoatControlQuest() -- Parse a book from the Ink file. local book = narrator.parse_file('stories.boat_control') local quest = Quest('boat control', book) quest.base = {} quest.base.activate = quest.activate quest.base.complete = quest.complete quest.boat = false quest.activate = function(this) print('activate...') local ent = ecs_get_player_entity() ecs_set_slot(this.boat.boat_id, ent, "seat1") -- ecs_character_set_actuator(ent, "sitting") ecs_character("set-actuator", ent, "idle") local boat_activated = function() -- local ent = ecs_get_player_entity() -- ecs_character_set_actuator(ent, "idle") -- ecs_character_physics_control(ent, false) -- ecs_character_params_set(ent, "gravity", false) -- ecs_character_params_set(ent, "buoyancy", false) end this.story:bind('boat_activated', boat_activated) this.base.activate(this) end quest.complete = function(this) this.base.complete(this) this.active = false local ent = ecs_get_player_entity() ecs_set_slot(this.boat.boat_id, this.boat.passengers[1], "seat0") ecs_character("set-actuator", ent, "sitting") ecs_set_slot(this.boat.boat_id, ent, "seat1") ecs_character("set-actuator", ent, "sitting") print("SLOT", "captain_seat", "boo1") ecs_set_slot(this.boat.boat_id, ent, "captain_seat") ecs_character("set-actuator", ent, "sitting") end return quest end function create_actuator() return { is_complete = false, complete = function(this) return this.is_complete end, finish = function(this) this.is_complete = true ecs_character("set-actuator", this.entity, "") ecs_character("physics-control", this.entity, true) print("COMPLETE") end, forward = function(this) if (this.forward_animation) then this:animation(this.forward_animation) end end, animation = function(this, animation) print("ANIMATION: ", animation) ecs_character("set-actuator", this.entity, animation) end, event = function(this, event, trigger_entity, what_entity) print("actuator events: ", event) if event == "actuator_forward" then this:forward() return true elseif event == "_in_actuator_forward" then this:forward() return true elseif event == "actuator_exit" then this:finish() return true end if this.finish_events then for i, p in ipairs(this.finish_events) do if p == event then this:finish() break end end if this.is_complete then return true end end return false end, } end quests = {} local actuator = nil function check_actuator_event(event, trigger_entity, what_entity) print("check_actuator_event: ", event) --[[ if event == "actuator_enter" then if not ecs_character("is-player", what_entity) then return end ecs_character("physics-control", what_entity, false) local animation = ecs_trigger_get_animation(trigger_entity) ecs_character("set-actuator", what_entity, animation) ecs_trigger_set_position(trigger_entity, what_entity) local ent = ecs_get_entity(what_entity) if (ent.is_character()) then print("character") end if (ent.is_player()) then print("player") end -- crash() actuator = create_actuator() actuator.trigger = trigger_entity actuator.entity = what_entity actuator.forward = function(this) this:animation("swimming-edge-climb") local ent = ecs_get_player_entity() ecs_character("params-set", ent, "gravity", true) ecs_character("params-set", ent, "buoyancy", true) end actuator.base_event = actuator.event actuator.finish_events = {"animation:swimming-edge-climb:end"} actuator.event = function(this, event, te, we) print("actuator events 1: ", event) if this.base_event(this, event, te, we) then return true end return false end ]]-- if event == "character_enter" then if not ecs_character("is-player", trigger_entity) then return end actuator = create_actuator() actuator.trigger = trigger_entity actuator.entity = trigger_entity actuator.other_entity = what_entity actuator.forward_animation = "pass-character" actuator.finish_events = {"animation:pass-character:end"} actuator.base_event = actuator.event actuator.event = function(this, event, te, we) print("actuator events 2: ", event) if event == "actuator_exit" then this:animation("idle") return true end if this.base_event(this, event, te, we) then return true end if event == "character_enter" then -- why? -- ecs_character_set_actuator(this.entity, "idle") -- ecs_character_set_actuator(this.entity, "idle") return true elseif event == "actuator_enter" then -- why? -- ecs_character_set_actuator(this.entity, "idle") -- ecs_character_set_actuator(this.entity, "idle") return true end return false end actuator:animation("idle") end end -- ecs_set_debug_drawing(true) local vehicles = {} local player_vehicles = {} local actuators = {} function create_vehicle(vtype, passengers, position) local vehicle = {} vehicle.id = ecs_vehicle_set(vtype, position[1], position[2], position[3], position[4]) vehicle.passengers = {} vehicle.actuators = {} vehicle.add_passenger = function(this, data) local npc_id = ecs_npc_set(data.model, data.position[1], data.position[2], data.position[3], data.position[4]) table.insert(this.passengers, npc_id) ecs_character("physics-control", npc_id, false) ecs_character("params-set", npc_id, "gravity", false) ecs_character("params-set", npc_id, "buoyancy", false) ecs_set_slot(this.id, npc_id, data.slot) ecs_character("set-actuator", npc_id, data.animation) end for i, v in ipairs(passengers) do vehicle:add_passenger(v) end return vehicle end function create_boat() local boat = create_vehicle("boat", { model = "normal-female.glb", position = {0, 2, -10, 1.75}, slot = "captain_seat", animation = "sitting"}, {0, 0, -10, 1.75}) --[[ boat.id = ecs_vehicle_set("boat", 0, 0, -10, 1.75) local npc_id = ecs_npc_set("normal-female.glb", 0, 2, -10, 1.75) boat.passengers = {npc_id} ecs_character("physics-control", npc_id, false) ecs_character("params-set", npc_id, "gravity", false) ecs_character("params-set", npc_id, "buoyancy", false) print("SLOT", "captain_seat", "boo") ecs_set_slot(boat.boat_id, npc_id, "captain_seat") ecs_character("set-actuator", npc_id, "sitting") -- ecs_set_animation_state(npc_id, "main", "actuator", true) -- ecs_set_animation_state(npc_id, "actuator-state", "sitting", true) ]]-- boat.event = function(this, event, event_data) print("boat: ", event) if event == "boat_control_enter" then local quest = BoatControlQuest() quest.boat = this quests[quest.name] = quest quest:activate() return true end if event == "boat_control_exit" then return true end return false end return boat end function create_actuator2(ent) print("create actuator") local act = { id = ent, activated = false, contained = {}, enter = function(this, what) print(this.id, "visited by", what) if not ecs_character("is-player", what) then -- actuators are only for players return end ecs_character("physics-control", what, false) local animation = ecs_trigger_get_animation(this.id) print(animation) ecs_character("set-actuator", what, animation) ecs_trigger_set_position(this.id, what) local ent = ecs_get_entity(what) if (ent.is_character()) then print("character") end if (ent.is_player()) then print("player") end table.insert(this.contained, what) this.activated = true print("position: ", _ecs.position(what).y) end, exit = function(this, what) print(this.id, "left by", what) if this.contained[1] ~= what then crash() end ecs_character("set-actuator", this.contained[1], "") ecs_character("physics-control", this.contained[1], true) this.activated = false print("COMPLETE") end, event = function(this, event, trigger, what) if this.activated then print("!!!", event) if event == "actuator_forward" then this:animation("swimming-edge-climb") local ent = this.contained[1] ecs_character("params-set", ent, "gravity", true) ecs_character("params-set", ent, "buoyancy", true) return true elseif event == "actuator_backward" then return true elseif event == "animation:swimming-edge-climb:end" then this:exit(this.contained[1]) return true end end return false end, animation = function(this, animation) if this.activated then print("ANIMATION: ", animation) local ent = this.contained[1] ecs_character("set-actuator", ent, animation) end end, } return act end function endswith(s, suffix) return string.sub(s, -#suffix) == suffix end function startswith(s, prefix) return string.sub(s, 1, #prefix) == prefix end setup_handler(function(event, trigger_entity, what_entity) print(event) local event_handled = false if startswith(event, "actuator_") and event ~= "actuator_created" then for i, act in ipairs(actuators) do if act.id == trigger_entity then if event == "actuator_enter" then if not act.activated then act:enter(what_entity) event_handled = true break end elseif event == "actuator_exit" then if act.activated then act:exit(what_entity) event_handled = true break end else if act.activated then if act:event(event, trigger_entity, what_entity) then event_handled = true break end end end event_handled = true end end elseif startswith(event, "animation:") and endswith(event, ":end") then for i, act in ipairs(actuators) do if act.activated then if act:event(event, trigger_entity, what_entity) then event_handled = true break end end end end if event_handled then return end if event == "actuator_enter" or event == "actuator_exit" or event == "actuator_forward" then print("bad event:", event, trigger_entity, what_entity) crash() end for k, v in pairs(quests) do if v.active then local event_data = {} event_data.trigger_entity = trigger_entity event_data.object_entity = what_entity v:event(event, event_data) end end for i, vehicle in ipairs(vehicles) do print(i, vehicle) if vehicle.event then local event_data = {} event_data.trigger_entity = trigger_entity event_data.object_entity = what_entity if vehicle:event(event, event_data) then event_handled = true end end end if event_handled then return end if event == "startup" then main_menu() elseif event == "narration_progress" then print("narration progress!") elseif event == "narration_answered" then local answer = narration_get_answer() print("answered:", answer) elseif event == "new_game" then local ent = ecs_get_player_entity() ecs_character("params-set", ent, "gravity", true) ecs_character("params-set", ent, "buoyancy", false) local quest = StartGameQuest() quests[quest.name] = quest for k, v in pairs(quests) do print(k, v.active) end quest:activate() local start_boat = create_boat() table.insert(vehicles, start_boat) table.insert(player_vehicles, start_boat) elseif event == "actuator_created" then print(trigger_entity) local act = create_actuator2(trigger_entity) table.insert(actuators, act) --[[ else if not actuator then check_actuator_event(event, trigger_entity, what_entity) else if not actuator:event(event, trigger_entity, what_entity) then crash() end if actuator:complete() then print("ACTUATOR COMPLETE") print("EXIT ACTUATOR") actuator = nil end end --]] end end)