Communication with NPC
In practice, we often encounter situations where we need to talk to NPCs, so here is a simple implementation of the "NPC Talk" function.
Brief Introduction
- camera follows unit movement
- Automatic selection of the unit to be operated
- Click on each NPC to bring up the information screen (dialogue screen) of the corresponding NPC
- Press
ECS
to close the information screen (dialogue screen)
Code
Methods
do
local boolNPCTalk = false -- Determining if you are in a conversation
-- Display unit information
function showUnitInfo(unit)
-- get data
local unitKey = unit:get_key()
local headIconID = unit:get_icon()
local bodyIconID = cli.get_unit_type_kv(unitKey, "UIKey")
local unitName = unit:get_name()
local unitDesc = cli.get_unit_desc(unitKey) --?? why descrip is not print? but it show on the UI
local talkContent = cli.get_unit_type_kv(unitKey, "talk")
-- write data
local player = cli.player(1)
local imageKeyHead = "8f8e2abf-d3e8-46f4-9390-f4aea1b16a64"
cli.ui:set_image(imageKeyHead, headIconID, player)
local imageKeyBody = "79c1cd94-b894-4a4c-81e0-6a10120e7872"
cli.ui:set_image(imageKeyBody, bodyIconID, player)
local textKeyName = "04df68a1-a9cb-432d-af29-b1a4560f1efc"
cli.ui:set_text(textKeyName, unitName, player)
local textKeyNameDesc = "dfe6540f-6633-461d-beb5-43e66807c621"
cli.ui:set_text(textKeyNameDesc, unitDesc, player)
local textKeyTalkContent = "e705e844-217e-41ac-ab91-6aba6e3b6b84"
cli.ui:set_text(textKeyTalkContent, talkContent, player)
end
-- Communication with NPC
function conversationWithNPC(unitSend, unitAccept)
local playerSend = unitSend:get_player()
if boolNPCTalk then
playerSend:msg("No new conversation is currently available!")
else
boolNPCTalk = true -- into conversation
showUnitInfo(unitAccept)
local talkElement = "58abace0-a760-4e6d-a116-f924e878e314"
cli.ui:set_enable(talkElement, true, playerSend)
-- poll judge distance
cli.timer(1, 0, function(timer)
local boolSwich = false -- whether to leave the chat area
-- judge distance
local pointUnitSent = unitSend:get_point()
local pointUnitAccept = unitAccept:get_point()
local distance = pointUnitSent * pointUnitAccept
if distance >= 500 then
boolSwich = true
playerSend:msg("Too far away, conversation ends!")
end
if not boolNPCTalk then
boolSwich = true
end
-- gc
if boolSwich then
hideConversationUI(playerSend) -- hide conversation UI
boolNPCTalk = false
timer:remove()
end
end)
end
end
-- Game initialization setup
function GameInit()
local player = cli.player(1)
local unit = cli.actor_unit(20)
player:select(unit)
player:camera_focus(unit)
end
-- Hide conversation UI
function hideConversationUI(player)
local talkElement = "58abace0-a760-4e6d-a116-f924e878e314"
cli.ui:set_enable(talkElement, false, player)
end
Events
-- Game initialisation events
cli.game:event("Game-Init", function()
GameInit() -- game init
end)
-- Player selected unit event
cli.game:event("Unit-SingleSelect", function(tri, ...)
local args = {...}
local unit = cli.actor_unit(20)
local player = unit:get_player()
if args[2]:get_key() ~= unit:get_key() and
args[1]:get_id() == player:get_id()
then
player:select(unit)
local unitPoint = unit:get_point()
local args2Point = args[2]:get_point()
local distance = unitPoint * args2Point
if distance < 400 then
conversationWithNPC(cli.actor_unit(20), args[2]) -- go conversation
else
player:msg("Too far away to talk!")
end
end
end)
-- Keyboard press events
cli.game:event("Keyboard-Down", function(tri, ...)
local args = {...}
if args[1]:get_id() == 1 and args[2] == KEY["ESC"] then
boolNPCTalk = false
end
end)
end
Download
link unvailable for now.