UNPKG

dcl-npc-toolkit-ai-version

Version:

A collection of tools for creating Non-Player-Characters (NPCs). These are capable of having conversations with the player, and play different animations. AI usage is added atop of it

130 lines 19.8 kB
import { TextShape, Transform, engine, inputSystem } from "@dcl/sdk/ecs"; import { IsFollowingPath, IsTypingBubble, IsTypingDialog, TrackUserFlag } from "./components"; import { activeNPC, walkingTimers } from "./npc"; import { ConfirmMode, closeTag, confirmText, npcDialogComponent, rushText, skipDialogs } from "./dialog"; import { bubbles, next } from "./bubble"; import { Quaternion, Vector3 } from "@dcl/sdk/math"; export function handlePathTimes(dt) { for (const [entity] of engine.getEntitiesWith(IsFollowingPath)) { if (walkingTimers.has(entity)) { let elapsed = walkingTimers.get(entity); elapsed += dt; walkingTimers.set(entity, walkingTimers.get(entity) + dt); } else { walkingTimers.set(entity, dt); } } } export function handleDialogTyping(dt) { for (const [entity] of engine.getEntitiesWith(IsTypingDialog)) { let dialogData = npcDialogComponent.get(entity); if (!dialogData.typing) { return; } dialogData.timer += dt; if (dialogData.timer >= 2 / dialogData.speed) { let charsToAdd = Math.floor(dialogData.timer / (1 / dialogData.speed)); dialogData.timer = 0; dialogData.visibleChars += charsToAdd; closeTag(dialogData, charsToAdd); if (dialogData.visibleChars >= dialogData.fullText.length) { dialogData.typing = false; dialogData.visibleChars = dialogData.fullText.length; IsTypingDialog.deleteFrom(entity); } dialogData.visibleText = dialogData.fullText.substr(0, dialogData.visibleChars); } } } export function handleBubbletyping(dt) { for (const [entity] of engine.getEntitiesWith(IsTypingBubble)) { let dialogData = bubbles.get(entity); if (dialogData.done) { continue; } dialogData.timer += dt; if (!dialogData.typing) { if (dialogData.timer > dialogData.timeOn) { dialogData.done = true; dialogData.typing = false; dialogData.timer = 0; next(entity); } } else if (dialogData.timer >= 2 / dialogData.speed) { let charsToAdd = Math.floor(dialogData.timer / (1 / dialogData.speed)); dialogData.timer = 0; dialogData.visibleChars += charsToAdd; if (dialogData.visibleChars >= dialogData.fullText.length || dialogData.done) { dialogData.typing = false; dialogData.visibleChars = dialogData.fullText.length; IsTypingDialog.deleteFrom(entity); } TextShape.getMutable(dialogData.text).text = dialogData.fullText.substr(0, dialogData.visibleChars); } } } export function faceUserSystem(dt) { for (const [entity, track] of engine.getEntitiesWith(TrackUserFlag)) { if (track.active) { const player = Transform.get(engine.PlayerEntity); let lookAtTarget = Vector3.create(player.position.x, player.position.y, player.position.z); let direction = Vector3.subtract(lookAtTarget, Transform.get(entity).position); let transform = Transform.getMutable(entity); transform.rotation = Quaternion.slerp(transform.rotation, Quaternion.lookRotation(direction), dt * track.rotSpeed); if (track.lockXZRotation) { transform.rotation.x = 0; transform.rotation.z = 0; } } } } export function inputListenerSystem() { const PET = inputSystem.isTriggered(1, 1); const PEP = inputSystem.isPressed(1); const PPET = inputSystem.isTriggered(0, 1); const PPEP = inputSystem.isPressed(0); const SET = inputSystem.isTriggered(2, 1); const SEP = inputSystem.isPressed(2); if (PPET && PPEP) { if (activeNPC) { let dialogData = npcDialogComponent.get(activeNPC); if (!dialogData.visible || Date.now() - dialogData.openTime < 100) return; if (dialogData.typing) { rushText(activeNPC); } else if (!dialogData.isQuestion) { confirmText(activeNPC, ConfirmMode.Next); } } } if (SET && SEP) { if (activeNPC) { let dialogData = npcDialogComponent.get(activeNPC); if (!dialogData.visible || Date.now() - dialogData.openTime < 100) return; if (dialogData.isQuestion) { confirmText(activeNPC, ConfirmMode.Confirm); } else if (!dialogData.isQuestion) { confirmText(activeNPC, ConfirmMode.Next); } } } if (PET && PEP) { if (activeNPC) { let dialogData = npcDialogComponent.get(activeNPC); if (!dialogData.visible || Date.now() - dialogData.openTime < 100) return; if (dialogData.isQuestion) { confirmText(activeNPC, ConfirmMode.Cancel); } else if (dialogData.script[dialogData.index].skipable && !dialogData.isFixedScreen) { skipDialogs(activeNPC); } } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdGVtcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zeXN0ZW1zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBeUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ2hILE9BQU8sRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDOUYsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFDakQsT0FBTyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLGtCQUFrQixFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDekcsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDekMsT0FBTyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFcEQsTUFBTSxVQUFVLGVBQWUsQ0FBQyxFQUFTO0lBQ3JDLEtBQUssTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxlQUFlLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztRQUM3RCxJQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUMsQ0FBQztZQUMxQixJQUFJLE9BQU8sR0FBVSxhQUFhLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBRSxDQUFBO1lBQy9DLE9BQU8sSUFBSSxFQUFFLENBQUE7WUFDYixhQUFhLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBRSxHQUFHLEVBQUUsQ0FBQyxDQUFBO1FBQzlELENBQUM7YUFDRyxDQUFDO1lBQ0QsYUFBYSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFDakMsQ0FBQztJ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QUtILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFbnRpdHksIElucHV0QWN0aW9uLCBQb2ludGVyRXZlbnRUeXBlLCBUZXh0U2hhcGUsIFRyYW5zZm9ybSwgZW5naW5lLCBpbnB1dFN5c3RlbSB9IGZyb20gXCJAZGNsL3Nkay9lY3NcIjtcbmltcG9ydCB7IElzRm9sbG93aW5nUGF0aCwgSXNUeXBpbmdCdWJibGUsIElzVHlwaW5nRGlhbG9nLCBUcmFja1VzZXJGbGFnIH0gZnJvbSBcIi4vY29tcG9uZW50c1wiO1xuaW1wb3J0IHsgYWN0aXZlTlBDLCB3YWxraW5nVGltZXJzIH0gZnJvbSBcIi4vbnBjXCI7XG5pbXBvcnQgeyBDb25maXJtTW9kZSwgY2xvc2VUYWcsIGNvbmZpcm1UZXh0LCBucGNEaWFsb2dDb21wb25lbnQsIHJ1c2hUZXh0LCBza2lwRGlhbG9ncyB9IGZyb20gXCIuL2RpYWxvZ1wiO1xuaW1wb3J0IHsgYnViYmxlcywgbmV4dCB9IGZyb20gXCIuL2J1YmJsZVwiO1xuaW1wb3J0IHsgUXVhdGVybmlvbiwgVmVjdG9yMyB9IGZyb20gXCJAZGNsL3Nkay9tYXRoXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVQYXRoVGltZXMoZHQ6bnVtYmVyKSB7XG4gICAgZm9yIChjb25zdCBbZW50aXR5XSBvZiBlbmdpbmUuZ2V0RW50aXRpZXNXaXRoKElzRm9sbG93aW5nUGF0aCkpIHtcbiAgICAgICAgaWYod2Fsa2luZ1RpbWVycy5oYXMoZW50aXR5KSl7XG4gICAgICAgICAgICBsZXQgZWxhcHNlZDpudW1iZXIgPSB3YWxraW5nVGltZXJzLmdldChlbnRpdHkpIVxuICAgICAgICAgICAgZWxhcHNlZCArPSBkdFxuICAgICAgICAgICAgd2Fsa2luZ1RpbWVycy5zZXQoZW50aXR5LCB3YWxraW5nVGltZXJzLmdldChlbnRpdHkpISArIGR0KVxuICAgICAgICB9XG4gICAgICAgIGVsc2V7XG4gICAgICAgICAgICB3YWxraW5nVGltZXJzLnNldChlbnRpdHksIGR0KVxuICAgICAgICB9XG4gICAgfVxuICB9XG5cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVEaWFsb2dUeXBpbmcoZHQ6bnVtYmVyKSB7XG4gICAgZm9yIChjb25zdCBbZW50aXR5XSBvZiBlbmdpbmUuZ2V0RW50aXRpZXNXaXRoKElzVHlwaW5nRGlhbG9nKSkge1xuICAgICAgICBsZXQgZGlhbG9nRGF0YSA9IG5wY0RpYWxvZ0NvbXBvbmVudC5nZXQoZW50aXR5KVxuICAgICAgICBpZighZGlhbG9nRGF0YS50eXBpbmcpe1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBkaWFsb2dEYXRhLnRpbWVyICs9IGR0XG4gICAgICAgIGlmIChkaWFsb2dEYXRhLnRpbWVyID49IDIgLyBkaWFsb2dEYXRhLnNwZWVkKSB7XG4gICAgICAgICAgICBsZXQgY2hhcnNUb0FkZCA9IE1hdGguZmxvb3IoZGlhbG9nRGF0YS50aW1lciAvICgxIC8gZGlhbG9nRGF0YS5zcGVlZCkpXG4gICAgICAgICAgICBkaWFsb2dEYXRhLnRpbWVyID0gMFxuXG4gICAgICAgICAgICBkaWFsb2dEYXRhLnZpc2libGVDaGFycyArPSBjaGFyc1RvQWRkXG4gICAgICAgICAgICBjbG9zZVRhZyhkaWFsb2dEYXRhLCBjaGFyc1RvQWRkKVxuXG5cbiAgICAgICAgICAgIGlmIChkaWFsb2dEYXRhLnZpc2libGVDaGFycyA+PSBkaWFsb2dEYXRhLmZ1bGxUZXh0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGRpYWxvZ0RhdGEudHlwaW5nID0gZmFsc2VcbiAgICAgICAgICAgICAgICBkaWFsb2dEYXRhLnZpc2libGVDaGFycyA9IGRpYWxvZ0RhdGEuZnVsbFRleHQubGVuZ3RoXG4gICAgICAgICAgICAgICAgSXNUeXBpbmdEaWFsb2cuZGVsZXRlRnJvbShlbnRpdHkpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRpYWxvZ0RhdGEudmlzaWJsZVRleHQgPSBkaWFsb2dEYXRhLmZ1bGxUZXh0LnN1YnN0cigwLCBkaWFsb2dEYXRhLnZpc2libGVDaGFycylcbiAgICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBoYW5kbGVCdWJibGV0eXBpbmcoZHQ6bnVtYmVyKSB7XG4gICAgZm9yIChjb25zdCBbZW50aXR5XSBvZiBlbmdpbmUuZ2V0RW50aXRpZXNXaXRoKElzVHlwaW5nQnViYmxlKSkge1xuICAgICAgICBsZXQgZGlhbG9nRGF0YSA9IGJ1YmJsZXMuZ2V0KGVudGl0eSlcbiAgICAgICAgaWYoZGlhbG9nRGF0YS5kb25lKXtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICBkaWFsb2dEYXRhLnRpbWVyICs9IGR0XG5cbiAgICAgICAgaWYgKCFkaWFsb2dEYXRhLnR5cGluZykge1xuICAgICAgICAgICAgaWYgKGRpYWxvZ0RhdGEudGltZXIgPiBkaWFsb2dEYXRhLnRpbWVPbikge1xuICAgICAgICAgICAgICAgIC8vZGlhbG9nRGF0YS5pc0J1YmJsZU9wZW4gPSBmYWxzZVxuICAgICAgICAgICAgICAgIGRpYWxvZ0RhdGEuZG9uZSA9IHRydWVcbiAgICAgICAgICAgICAgICBkaWFsb2dEYXRhLnR5cGluZyA9IGZhbHNlXG4gICAgICAgICAgICAgICAgZGlhbG9nRGF0YS50aW1lciA9IDBcbiAgICAgICAgICAgICAgICBuZXh0KGVudGl0eSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgZWxzZSBpZiAoZGlhbG9nRGF0YS50aW1lciA+PSAyIC8gZGlhbG9nRGF0YS5zcGVlZCkge1xuICAgICAgICAgICAgbGV0IGNoYXJzVG9BZGQgPSBNYXRoLmZsb29yKGRpYWxvZ0RhdGEudGltZXIgLyAoMSAvIGRpYWxvZ0RhdGEuc3BlZWQpKVxuICAgICAgICAgICAgZGlhbG9nRGF0YS50aW1lciA9IDBcbiAgICAgICAgICAgIGRpYWxvZ0RhdGEudmlzaWJsZUNoYXJzICs9IGNoYXJzVG9BZGRcbiAgICAgICAgXG4gICAgICAgICAgICBpZiAoZGlhbG9nRGF0YS52aXNpYmxlQ2hhcnMgPj0gZGlhbG9nRGF0YS5mdWxsVGV4dC5sZW5ndGggfHwgZGlhbG9nRGF0YS5kb25lKSB7XG4gICAgICAgICAgICAgICAgZGlhbG9nRGF0YS50eXBpbmcgPSBmYWxzZVxuICAgICAgICAgICAgICAgIGRpYWxvZ0RhdGEudmlzaWJsZUNoYXJzID0gZGlhbG9nRGF0YS5mdWxsVGV4dC5sZW5ndGhcbiAgICAgICAgICAgICAgICBJc1R5cGluZ0RpYWxvZy5kZWxldGVGcm9tKGVudGl0eSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFRleHRTaGFwZS5nZXRNdXRhYmxlKGRpYWxvZ0RhdGEudGV4dCkudGV4dCA9IGRpYWxvZ0RhdGEuZnVsbFRleHQuc3Vic3RyKDAsIGRpYWxvZ0RhdGEudmlzaWJsZUNoYXJzKVxuICAgICAgICB9XG4gICAgfVxuICB9XG5cbmV4cG9ydCBmdW5jdGlvbiBmYWNlVXNlclN5c3RlbShkdDogbnVtYmVyKSB7XG4gIGZvciAoY29uc3QgW2VudGl0eSwgdHJhY2tdIG9mIGVuZ2luZS5nZXRFbnRpdGllc1dpdGgoVHJhY2tVc2VyRmxhZykpIHtcbiAgICBpZiAodHJhY2suYWN0aXZlKSB7XG4gICAgICBjb25zdCBwbGF5ZXIgPSBUcmFuc2Zvcm0uZ2V0KGVuZ2luZS5QbGF5ZXJFbnRpdHkpXG4gICAgICBsZXQgbG9va0F0VGFyZ2V0ID0gVmVjdG9yMy5jcmVhdGUocGxheWVyLnBvc2l0aW9uLngsIHBsYXllci5wb3NpdGlvbi55LCBwbGF5ZXIucG9zaXRpb24ueilcbiAgICAgIGxldCBkaXJlY3Rpb24gPSBWZWN0b3IzLnN1YnRyYWN0KGxvb2tBdFRhcmdldCwgVHJhbnNmb3JtLmdldChlbnRpdHkpLnBvc2l0aW9uKVxuXG4gICAgICBsZXQgdHJhbnNmb3JtID0gVHJhbnNmb3JtLmdldE11dGFibGUoZW50aXR5KVxuICAgICAgdHJhbnNmb3JtLnJvdGF0aW9uID0gUXVhdGVybmlvbi5zbGVycCh0cmFuc2Zvcm0ucm90YXRpb24sIFF1YXRlcm5pb24ubG9va1JvdGF0aW9uKGRpcmVjdGlvbiksIGR0ICogdHJhY2sucm90U3BlZWQpXG5cbiAgICAgIGlmICh0cmFjay5sb2NrWFpSb3RhdGlvbikge1xuICAgICAgICB0cmFuc2Zvcm0ucm90YXRpb24ueCA9IDBcbiAgICAgICAgdHJhbnNmb3JtLnJvdGF0aW9uLnogPSAwXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbnB1dExpc3RlbmVyU3lzdGVtKCl7XG4gIGNvbnN0IFBFVCA9IGlucHV0U3lzdGVtLmlzVHJpZ2dlcmVkKElucHV0QWN0aW9uLklBX1BSSU1BUlksUG9pbnRlckV2ZW50VHlwZS5QRVRfRE9XTilcbiAgY29uc3QgUEVQID0gaW5wdXRTeXN0ZW0uaXNQcmVzc2VkKElucHV0QWN0aW9uLklBX1BSSU1BUlkpXG5cbiAgY29uc3QgUFBFVCA9IGlucHV0U3lzdGVtLmlzVHJpZ2dlcmVkKElucHV0QWN0aW9uLklBX1BPSU5URVIsUG9pbnRlckV2ZW50VHlwZS5QRVRfRE9XTilcbiAgY29uc3QgUFBFUCA9IGlucHV0U3lzdGVtLmlzUHJlc3NlZChJbnB1dEFjdGlvbi5JQV9QT0lOVEVSKVxuXG4gIGNvbnN0IFNFVCA9IGlucHV0U3lzdGVtLmlzVHJpZ2dlcmVkKElucHV0QWN0aW9uLklBX1NFQ09OREFSWSxQb2ludGVyRXZlbnRUeXBlLlBFVF9ET1dOKVxuICBjb25zdCBTRVAgPSBpbnB1dFN5c3RlbS5pc1ByZXNzZWQoSW5wdXRBY3Rpb24uSUFfU0VDT05EQVJZKVxuXG4gIGlmKFBQRVQgJiYgUFBFUCl7XG4gICAgaWYoYWN0aXZlTlBDKXtcbiAgICAgIGxldCBkaWFsb2dEYXRhID0gbnBjRGlhbG9nQ29tcG9uZW50LmdldChhY3RpdmVOUEMpXG4gICAgICBpZighZGlhbG9nRGF0YS52aXNpYmxlIHx8IERhdGUubm93KCkgLSBkaWFsb2dEYXRhLm9wZW5UaW1lIDwgMTAwKXJldHVyblxuICAgICAgaWYoZGlhbG9nRGF0YS50eXBpbmcpe1xuICAgICAgICBydXNoVGV4dChhY3RpdmVOUEMpXG4gICAgICB9ZWxzZSBpZighZGlhbG9nRGF0YS5pc1F1ZXN0aW9uKXtcbiAgICAgICAgY29uZmlybVRleHQoYWN0aXZlTlBDLCBDb25maXJtTW9kZS5OZXh0KVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmKFNFVCAmJiBTRVApe1xuICAgIGlmKGFjdGl2ZU5QQyl7XG4gICAgICBsZXQgZGlhbG9nRGF0YSA9IG5wY0RpYWxvZ0NvbXBvbmVudC5nZXQoYWN0aXZlTlBDKVxuICAgICAgaWYoIWRpYWxvZ0RhdGEudmlzaWJsZSB8fCBEYXRlLm5vdygpIC0gZGlhbG9nRGF0YS5vcGVuVGltZSA8IDEwMClyZXR1cm5cbiAgICAgIGlmKGRpYWxvZ0RhdGEuaXNRdWVzdGlvbil7XG4gICAgICAgIGNvbmZpcm1UZXh0KGFjdGl2ZU5QQywgQ29uZmlybU1vZGUuQ29uZmlybSlcbiAgICAgIH1lbHNlIGlmKCFkaWFsb2dEYXRhLmlzUXVlc3Rpb24pe1xuICAgICAgICBjb25maXJtVGV4dChhY3RpdmVOUEMsIENvbmZpcm1Nb2RlLk5leHQpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYoUEVUICYmIFBFUCl7XG4gICAgaWYoYWN0aXZlTlBDKXtcbiAgICAgIGxldCBkaWFsb2dEYXRhID0gbnBjRGlhbG9nQ29tcG9uZW50LmdldChhY3RpdmVOUEMpXG4gICAgICBpZighZGlhbG9nRGF0YS52aXNpYmxlIHx8IERhdGUubm93KCkgLSBkaWFsb2dEYXRhLm9wZW5UaW1lIDwgMTAwKXJldHVyblxuICAgICAgaWYoZGlhbG9nRGF0YS5pc1F1ZXN0aW9uKXtcbiAgICAgICAgY29uZmlybVRleHQoYWN0aXZlTlBDLCBDb25maXJtTW9kZS5DYW5jZWwpXG4gICAgICB9ZWxzZSBpZihkaWFsb2dEYXRhLnNjcmlwdFtkaWFsb2dEYXRhLmluZGV4XS5za2lwYWJsZSAmJiAhZGlhbG9nRGF0YS5pc0ZpeGVkU2NyZWVuKXtcbiAgICAgICAgc2tpcERpYWxvZ3MoYWN0aXZlTlBDKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG5cblxuLy9cbn0iXX0=