StendhalScripting/Lua: Difference between revisions

Content deleted Content added
imported>AntumDeluge
Stendhal Application: update for changes to Lua engine
imported>AntumDeluge
add categories
 
(19 intermediate revisions by the same user not shown)
Line 50:
-- table variable
local var4 = {}
</pre>
 
=== Strings ===
 
==== String Concatenation ====
 
String concatenation is simple, much like Java uses a plus operator (<code>+</code>) to join strings, Lua uses two periods (<code>..</code>).
 
Example:
<pre>
-- create a string variable
local var = "Hello"
 
-- append another string
var = var .. " world!"
 
print(var) -- prints "Hello world!"
</pre>
 
Line 57 ⟶ 74:
 
''(<span style="color:red;">IMPORTANT NOTE: Lua table indexes begin at 1, not 0</span>)''
 
==== Creating Tables ====
 
An empty table is initialized with a pair of curly braces (<code>{}</code>):
Line 66 ⟶ 85:
<pre>
-- create a table with values
local mytable = {"foo"}
"foo"
}
 
-- add value
Line 76 ⟶ 93:
To create a key=value table, any of the following methods can be used to add values:
<pre>
-- all of these do the same thing, that is, assigning "bar" to mytable.foo
local mytable {
foo = "bar",
["foo"] = "bar",
}
 
mytable.foo = "bar"
mytable["foo"] = "bar"
</pre>
 
==== Accessing Table Values ====
 
Square brackets (<code>[]</code>) enclosing an index number are used to access values in indexed tables (''remember that Lua table indexes start at "1" not "0"''):
<pre>
local mytable = {"foo", "bar"}
 
print(mytable[1]) -- prints "foo"
print(mytable[2]) -- prints "bar"
</pre>
 
In a key=value table, values can be accessed by either enclosing the key string in square brackets or concatenating the key member using a <code>.</code>:
<pre>
local mytable = {foo="bar"}
 
-- using square brackets
print(mytable["foo"]) -- prints "bar"
 
-- using concatenated member
print(mytable.foo) -- prints "bar"
</pre>
 
==== Iterating Tables ====
 
Tables can be iterated in a ''<code>for''</code> loop using the ''<code>pairs''</code> or ''<code>ipairs''</code> iterators. Loops are terminated with the <code>end</code> keyword:
<pre>
local mytable = {"foo", "bar"}
"foo",
"bar",
}
 
print("indexes:")
Line 151 ⟶ 186:
Like normal variables, functions can be declared as '''global''' or '''local''' & must be terminated with the <code>end</code> keyword.
 
There are two ways to declaredefine functions with the <code>function</code> keyword:
<pre>
local function myFunction()
Line 165 ⟶ 200:
</pre>
 
Functions can also be valuesmembers inof a table:
<pre>
local myTable = {}
Line 243 ⟶ 278:
=== Add Zone Music ===
 
Music can be added to zones with the <code>setZoneMusicgame:setMusic</code> global function. It supports the following arguments:
* ''<span style="color:darkgreen; font-style:italic;>filename:''</span> Basename of the OGG audio file to use stored in {{StendhalFile|master|data/music|data/music}}.
* <span style="color:darkgreen; font-style:italic;>args:</span> A table of key=value integers.
* ''volume:'' (optional) Volume level.
* Valid keys:
* ''x:'' (optional) The horizontal point for the source of the music.
** <span style="color:darkblue; font-style:italic;">volume:</span> Volume level (default: 100).
* ''y:'' (optional) The vertical point for the source of the music.
** ''<span style="color:darkblue; font-style:italic;">x:'' (optional)</span> The horizontal point for the source of the music (default: 1).
* ''radius:'' (optional) The radial range at which the music can be heard.
** ''<span style="color:darkblue; font-style:italic;">y:'' (optional)</span> The vertical point for the source of the music (default: 1).
** ''<span style="color:darkblue; font-style:italic;">radius:'' (optional)</span> The radial range at which the music can be heard (default: 10000).
 
Example:
<pre>
if game:setZone("0_semos_plains_n") then
setZoneMusicgame:setMusic("pleasant_creek_loop", {volume=85, radius=100})
end
</pre>
Line 300 ⟶ 337:
}
 
entitiesnpc:setPath(npc, nodes)
-- Use helper object to create NPC path
entities:setPath(npc, nodes)
 
-- Dialogue
Line 329 ⟶ 365:
This simply adds a response to saying "hello" & sets the NPC to attend to the player (equivalent of <code>frank:addGreeting("Hello")</code>).
 
For more complicated behavior, we need to use some helper methods. If we want to check a condition we use the <code>newConditionconditions:create</code> globalmethod. function:The first parameter is the string name of the ChatCondition we want to instantiate. The second parameter is a table that contains the values that should be passed to the ChatCondition constructor.
 
Example:
<pre>
frank:add(ConversationStates.IDLE,
ConversationPhrases.GREETING_MESSAGES,
newConditionconditions:create("PlayerHasItemWithHimCondition", {"money"}),
ConversationStates.ATTENDING,
"Hello.",
Line 341 ⟶ 379:
In this scenario, the NPC will only respond if the player is carrying <item>money</item>.
 
A NotCondition instance can be created with the <code>newNotCondition</code> global function or using the <code>conditions.notactions:notCondition</code> method:
 
Example usage:
<pre>
local condition = conditions.notnotCondition(newConditionconditions:create("PlayerHasItemWithHimCondition", {"money"})
-- using newNotCondition
local condition = newNotCondition("PlayerHasItemWithHimCondition", "money")
 
-- using conditions.not
local condition = conditions.not(newCondition("PlayerHasItemWithHimCondition", "money")
</pre>
 
To add a ChatAction, we use the <code>newActionactions:create</code> globalmethod. functionIts usage is identical to <code>conditions:create</code>.
 
Example:
<pre>
frank:add(ConversationStates.IDLE,
ConversationPhrases.GREETING_MESSAGES,
newConditionconditions:create("PlayerHasItemWithHimCondition", {"money"}),
ConversationStates.ATTENDING,
"Hello.",
newActionactions:create("NPCEmoteAction", {"looks greedily at your pouch of money.", false}))
</pre>
 
Line 367 ⟶ 403:
ConversationPhrases.GREETING_MESSAGES,
{
newConditionconditions:create("PlayerHasItemWithHimCondition", {"money"}),
newNotConditionconditions:notCondition(newConditionconditions:create("NakedCondition")),
},
ConversationStates.ATTENDING,
nil,
{
newActionactions:create("SayTextAction", {"Hello."}),
newActionactions:create("NPCEmoteAction", {"looks greedily at your pouch of money.", false}),
})
</pre>
Line 383 ⟶ 419:
<pre>
local conditions = {
newConditionconditions:create("PlayerHasItemWithHimCondition", {"money"}),
{
newNotConditionconditions:notCondition(newConditionconditions:create("NakedCondition")),
},
}
Line 395 ⟶ 431:
nil,
{
newActionactions:create("SayTextAction", {"Hello."}),
newActionactions:create("NPCEmoteAction", {"looks greedily at your pouch of money.", false}),
})
 
</pre>
 
Line 478 ⟶ 513:
end
</pre>
 
== Misc ==
 
=== Typecasting ===
 
Lua does not support typecasting (as far as I know), but if the class you want to cast to has a copy constructor, achieving the same functionality is quite simple.
 
<pre>
-- "entities:getItem" returns an instance of Item
local bestiary = entities:getItem("bestiary")
 
-- in order to use the bestiary's "setOwner" method, we must convert it to an "OwnedItem" instance by calling its copy constructor
bestiary = luajava.newInstance("games.stendhal.server.entity.item.OwnedItem", bestiary)
bestiary:setOwner("Ted")
</pre>
 
= See Also =
 
* [[StendhalScripting/LuaAPI|Lua API]]
 
 
[[Category:Stendhal]]
[[Category:Documentation]]
[[Category:API]]
[[Category:Scripting]]
[[Category:Lua]]