I'd take no credits for this script this script was offically made by jkotni6,and I'm not sure if there is something like this.
Add this like to data/actions/actions.xml
You may change the uniqueid if you do want so.
Next, create a file in data/actions/scripts/ and name it smith.lua
Let me explain some things.
1. The first function is made by myself, I used a script from here as a template!
2. The second function is made totaly by myself, I've been working hard to get that few lines working.
3. There is an ITEMS array with sub-arrays. Here you will configure it like this:
The first number is the count of the item that should be smithed.
The second number is the item ID.
The third value is the item name (optional).
This example array is made to smith 2 items. To add more items just dublicate the first line, but do not go over 7 items because it might lag the server after 7.
Example:
Old:
New:
Also if you want more items to be smithed dublicate the first sub-array.
Example:
Old:
New:
Woah, we're already at the onUse function! More to go. ^^
This is it how it looks like. I'll explain the smith() function now a bit detailed.
The first attribute is the array that should be used. In this case it's the 1st sub array. The second attribute is the level position, the third the required item field and the fourth the position where the item should be created. The last 2 attributes are the item ID of the item that should be created and the item count.
YAY! We're done with the action script. Let's go to the NPC.
In data/npc/ create a file named Blacksmith Reider (you can change it if you want):
Now we come to the next part. In data/npc/scripts/ create a file named smith.lua:
Let's go to the configure part.
I believe that I don't have to explain the string configuration. I'll start with the arrays. The first, advance is the array of keywords the player should say to advance to the next smithing level. The next, task, is the array of keywords with which the player can check what he has to bring for the next level-up. The third contains keywords, that can tell you the smithing level (stat).
And now to the last, item.
It's the same as with the actions, there are sub-arrays, so I don't have to explain the sub array thing once more.
Last thing... add this to data/npc/scripts/lib/npc.lua:
Yay! we're finaly done! Please not that this isn't the finished script so you'll have to add a party with get/setPlayerStorageValue to the smith.lua files.
Also one more thing. The items that are required for the smithing of an item must be in the exact order as they are listed in the array! The first is on the top, the last on the bottom!
If you have any question, feel free to ask.
------------------------------------------------
How to smith?
So here we are. Add these lines
between
and
Also add these lines for each item that can be smithed.
Now it shouldn't be all to hard to add the items to the smith.lua action file...
This part:
would become something like this:
Add this like to data/actions/actions.xml
HTML:
<action uniqueid="1337" script="smith.lua" />
Next, create a file in data/actions/scripts/ and name it smith.lua
PHP:
function getItemsfromPos(position)
local toret = { }
if position.stackpos == nil then
position.stackpos = 1
end
while true do
local thing = getThingfromPos(position)
if thing.itemid == 0 then
break
end
if thing.type <= 0 then
thing.type = 1
end
table.insert(toret, {position.stackpos, thing.itemid, thing.type})
position.stackpos = position.stackpos + 1
end
return toret
end
function smith(array, pos1, pos2, pos3, createdItem, createdCount)
-- lever pos, items pos, anvil pos
t = getItemsfromPos({x=pos2.x, y=pos2.y, z=pos2.z, stackpos=0})
local y = { }
local delete = true
local txt = ''
for q = 1, #t do
for w = 1, #array do
if array[w][2] == t[q][2] and array[w][1] <= t[q][3] then
table.insert(y, {t[q][1], t[q][2], t[q][3]})
end
end
end
for x = 1, #array do
for z = 1, #y do
if array[x][2] ~= y[z][2] or array[x][1] > y[z][3] then
delete = false
end
if array[x][2] == y[z][2] and array[x][1] <= y[z][3] and delete == true then
thing = getThingfromPos({x=pos2.x, y=pos2.y, z=pos2.z, stackpos=y[z][1]})
doRemoveItem(thing.uid, array[x][1])
doSendMagicEffect(pos2, 15)
create = true
end
end
end
if create == true then
doCreateItem(createdItem, createdCount, {x=pos3.x, y=pos3.y, z=pos3.z, stackpos=1})
create = false
doSendMagicEffect(pos1, 3)
doSendMagicEffect(pos3, 11)
doSendAnimatedText(pos3, 'BANG!', 12)
end
end
local ITEMS = {
{
{2, 2152, ''},
{2, 2148, ''},
{1, 2000, ''}
},
{
{100, 2152, ''},
{10, 2160, ''}
}
}
function onUse(cid, item, frompos, item2, topos)
if item.uid == 1337 and item.itemid == 1945 then
smith(ITEMS[1], {x=85, y=28, z=9}, {x=85, y=27, z=9}, {x=85, y=29, z=9}, 2408, 1)
doTransformItem(item.uid, item.itemid+1)
elseif item.uid == 1337 and item.itemid == 1946 then
doTransformItem(item.uid, item.itemid-1)
end
end
1. The first function is made by myself, I used a script from here as a template!
2. The second function is made totaly by myself, I've been working hard to get that few lines working.
3. There is an ITEMS array with sub-arrays. Here you will configure it like this:
The first number is the count of the item that should be smithed.
The second number is the item ID.
The third value is the item name (optional).
PHP:
local ITEMS = {
{
{2, 2152, ''},
{2, 2148, ''},
{1, 2000, ''}
},
{
{100, 2152, ''},
{10, 2160, ''}
}
}
Example:
Old:
PHP:
local ITEMS = {
{
{2, 2152, ''},
{2, 2148, ''},
{1, 2000, ''}
},
{
{100, 2152, ''},
{10, 2160, ''}
}
}
PHP:
local ITEMS = {
{
{1, 1756, ''},
{2, 2152, ''},
{2, 2148, ''},
{1, 2000, ''}
},
{
{100, 2152, ''},
{10, 2160, ''}
}
}
Example:
Old:
PHP:
local ITEMS = {
{
{2, 2152, ''},
{2, 2148, ''},
{1, 2000, ''}
},
{
{100, 2152, ''},
{10, 2160, ''}
}
}
PHP:
local ITEMS = {
{
{2, 2152, ''},
{2, 2148, ''},
{1, 2000, ''}
},
{
{1, 1457, ''},
{1, 2684, ''},
{1, 1836, ''}
},
{
{100, 2152, ''},
{10, 2160, ''}
}
}
PHP:
function onUse(cid, item, frompos, item2, topos)
if item.uid == 1337 and item.itemid == 1945 then
smith(ITEMS[1], {x=85, y=28, z=9}, {x=85, y=27, z=9}, {x=85, y=29, z=9}, 2408, 1)
doTransformItem(item.uid, item.itemid+1)
elseif item.uid == 1337 and item.itemid == 1946 then
doTransformItem(item.uid, item.itemid-1)
end
end
The first attribute is the array that should be used. In this case it's the 1st sub array. The second attribute is the level position, the third the required item field and the fourth the position where the item should be created. The last 2 attributes are the item ID of the item that should be created and the item count.
YAY! We're done with the action script. Let's go to the NPC.
In data/npc/ create a file named Blacksmith Reider (you can change it if you want):
HTML:
<?xml version="1.0"?>
<npc name="Blacksmith Reider" script="data/npc/scripts/smith.lua" access="5" autowalk="25" floorchange="0" lookdir="2" level="1" maglevel="1">
<health now="120" max="120" />
<mana now="35" max="35" />
<look type="160" head="95" body="106" legs="87" feet="116" />
<parameters>
<parameter key="message_greet" value="Ohh... hello |PLAYERNAME|. What brings you to this place?" />
<parameter key="module_keywords" value="1" />
<parameter key="keywords" value="job;name" />
<parameter key="keyword_reply1" value="I'm a smith as you can see. I can teach you how to smith the best items you've ever dreamt off." />
<parameter key="keyword_reply2" value="My name... it's Reider of course!" />
<parameter key="message_farewell" value="Good bye young adventurer. Visit me sometime again." />
</parameters>
</npc>
Now we come to the next part. In data/npc/scripts/ create a file named smith.lua:
PHP:
function readAndStoreIt(startPhrase, middlePhrase1, middlePhrase2, endPhrase, array)
phrase = startPhrase
for q = 1, #array do
if array[q][1] == 1 then
middlePhrase = middlePhrase1
else
middlePhrase = middlePhrase2
end
phrase = phrase .. array[q][1] .. middlePhrase .. array[q][2]
if q == (#array - 1) then
phrase = phrase .. ' and '
elseif q < (#array - 1) then
phrase = phrase .. ', '
end
end
phrase = phrase .. endPhrase
return phrase
end
function getPlayerItemCountArray(cid, array)
v = true
for q = 1, #array do
if getPlayerItemCount(cid, array[q][3]) < array[q][1] then
v = false
end
end
return v
end
function doPlayerTakeItemArray(cid, array)
v = true
for q = 1, #array do
if doPlayerTakeItem(cid, array[q][3], array[q][1]) ~= 0 then
v = false
end
end
return v
end
talkState = 0
req = ''
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
-- OTServ event handling functions start
function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end
function onThink() npcHandler:onThink() end
-- OTServ event handling functions end
function creatureSayCallback(cid, type, msg)
if(npcHandler.focus ~= cid) then
return false
end
local welcome = 'I have written down your name into my book. When you are ready for an advance just come and I will find a task for you.'
local cancel = 'Maybe next time.'
local levelup = 'You brought all the items. Would you like to get a better smith?'
local done = 'Thank you very much for the items. If you would like to get even better just ask me for more lessons.'
local removeError = 'Sorry, but could not remove all items. Please contact the owner!'
local req1 = 'Please come back when you get '
local req2 = ' piece of '
local req3 = ' pieces of '
local req4 = '.'
local advance = {'advance', 'learn', 'lesson', 'teach'}
local task = {'task', 'mission', 'item', 'items'}
local stat = {'status', 'skill', 'level'}
local item = {
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
}
}
local strgVal = 667
local status = getPlayerStorageValue(cid, strgVal)
if msgInArray(stat, msg) then
if status < 0 then
selfSay('Your smithing skill is currently at ' .. status .. req4)
else
selfSay('Sorry, but you can not smith yet. Shall I teach you?')
end
talkState = 0
elseif msgInArray(task, msg) then
if (status + 1) <= #item then
req = readAndStoreIt('To get a better smith you should bring me ', ' piece of ', ' pieces of ', '.', item[status + 1])
selfSay(req)
talkState = 0
else
selfSay('Sorry, but currently I have no tasks for you.')
end
end
if status < 0 then
if msgInArray(advance, msg) then
selfSay('Do you realy want to learn how to smith items?')
talkState = 1
elseif msgcontains(msg, 'yes') and talkState == 1 then
selfSay(welcome)
talkState = 0
setPlayerStorageValue(cid, strgVal, 0)
elseif msgcontains(msg, 'no') and talkState == 1 then
selfSay(cancel)
talkState = 0
end
elseif status == 0 then
if msgInArray(advance, msg) then
if getPlayerItemCountArray(cid, item[1]) then
selfSay(levelup)
talkState = 1
else
req = readAndStoreIt(req1, req2, req3, req4, item[1])
selfSay(req)
talkState = 0
end
elseif msgcontains(msg, 'yes') and talkState == 1 then
if getPlayerItemCountArray(cid, item[1]) then
if doPlayerTakeItemArray(cid, item[1]) then
selfSay(done)
setPlayerStorageValue(cid, strgVal, 1)
else
selfSay(removeError)
end
else
req = readAndStoreIt(req1, req2, req3, req4, item[1])
selfSay(req)
end
talkState = 0
elseif msgcontains(msg, 'no') and talkState == 1 then
selfSay(cancel)
talkState = 0
end
elseif status == 1 then
if msgInArray(advance, msg) then
if getPlayerItemCountArray(cid, item[2]) then
selfSay(levelup)
talkState = 1
else
req = readAndStoreIt(req1, req2, req3, req4, item[2])
selfSay(req)
talkState = 0
end
elseif msgcontains(msg, 'yes') and talkState == 1 then
if getPlayerItemCountArray(cid, item[2]) then
if doPlayerTakeItemArray(cid, item[2]) then
selfSay(done)
setPlayerStorageValue(cid, strgVal, 2)
else
selfSay(removeError)
end
else
req = readAndStoreIt(req1, req2, req3, req4, item[2])
selfSay(req)
end
talkState = 0
elseif msgcontains(msg, 'no') and talkState == 1 then
selfSay(cancel)
talkState = 0
end
elseif status == 2 then
if msgInArray(advance, msg) then
if getPlayerItemCountArray(cid, item[3]) then
selfSay(levelup)
talkState = 1
else
req = readAndStoreIt(req1, req2, req3, req4, item[3])
selfSay(req)
talkState = 0
end
elseif msgcontains(msg, 'yes') and talkState == 1 then
if getPlayerItemCountArray(cid, item[3]) then
if doPlayerTakeItemArray(cid, item[3]) then
selfSay(done)
setPlayerStorageValue(cid, strgVal, 3)
else
selfSay(removeError)
end
else
req = readAndStoreIt(req1, req2, req3, req4, item[3])
selfSay(req)
end
talkState = 0
elseif msgcontains(msg, 'no') and talkState == 1 then
selfSay(cancel)
talkState = 0
end
elseif status == 3 then
if msgInArray(advance, msg) then
if getPlayerItemCountArray(cid, item[4]) then
selfSay(levelup)
talkState = 1
else
req = readAndStoreIt(req1, req2, req3, req4, item[4])
selfSay(req)
talkState = 0
end
elseif msgcontains(msg, 'yes') and talkState == 1 then
if getPlayerItemCountArray(cid, item[4]) then
if doPlayerTakeItemArray(cid, item[4]) then
selfSay(done)
setPlayerStorageValue(cid, strgVal, 4)
else
selfSay(removeError)
end
else
req = readAndStoreIt(req1, req2, req3, req4, item[4])
selfSay(req)
end
talkState = 0
elseif msgcontains(msg, 'no') and talkState == 1 then
selfSay(cancel)
talkState = 0
end
elseif status == 4 then
if msgInArray(advance, msg) then
if getPlayerItemCountArray(cid, item[5]) then
selfSay(levelup)
talkState = 1
else
req = readAndStoreIt(req1, req2, req3, req4, item[5])
selfSay(req)
talkState = 0
end
elseif msgcontains(msg, 'yes') and talkState == 1 then
if getPlayerItemCountArray(cid, item[5]) then
if doPlayerTakeItemArray(cid, item[5]) then
selfSay(done)
setPlayerStorageValue(cid, strgVal, 5)
else
selfSay(removeError)
end
else
req = readAndStoreIt(req1, req2, req3, req4, item[5])
selfSay(req)
end
talkState = 0
elseif msgcontains(msg, 'no') and talkState == 1 then
selfSay(cancel)
talkState = 0
end
elseif status == 5 then
if msgInArray(advance, msg) then
selfSay('Sorry, but I taught you every thing I do know.')
end
end
return true
end
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
Let's go to the configure part.
PHP:
local welcome = 'I have written down your name into my book. When you are ready for an advance just come and I will find a task for you.'
local cancel = 'Maybe next time.'
local levelup = 'You brought all the items. Would you like to get a better smith?'
local done = 'Thank you very much for the items. If you would like to get even better just ask me for more lessons.'
local removeError = 'Sorry, but could not remove all items. Please contact the owner!'
local req1 = 'Please come back when you get '
local req2 = ' piece of '
local req3 = ' pieces of '
local req4 = '.'
local advance = {'advance', 'learn', 'lesson', 'teach'}
local task = {'task', 'mission', 'item', 'items'}
local stat = {'status', 'skill', 'level'}
local item = {
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
}
}
local strgVal = 667
local status = getPlayerStorageValue(cid, strgVal)
I believe that I don't have to explain the string configuration. I'll start with the arrays. The first, advance is the array of keywords the player should say to advance to the next smithing level. The next, task, is the array of keywords with which the player can check what he has to bring for the next level-up. The third contains keywords, that can tell you the smithing level (stat).
And now to the last, item.
PHP:
local item = {
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
},
{
{50, 'iron ore', 2148},
{200, 'some ore', 2152},
{1000, 'gold', 2160}
}
}
Last thing... add this to data/npc/scripts/lib/npc.lua:
PHP:
function msgInArray(array, msg)
local v = false
msg = string.lower(msg)
for a = 1, #array do
if msgcontains(msg, array[a]) then
v = true
end
end
return v
end
Also one more thing. The items that are required for the smithing of an item must be in the exact order as they are listed in the array! The first is on the top, the last on the bottom!
If you have any question, feel free to ask.
------------------------------------------------
How to smith?
So here we are. Add these lines
PHP:
elseif msgInArray({'smith', 'create'}, msg) then
selfSay('You may smith one of the following items: ITEM LIST HERE')
talkState = 1
PHP:
if msgInArray(stat, msg) then
if status < 0 then
selfSay('Your smithing skill is currently at ' .. status .. req4)
else
selfSay('Sorry, but you can not smith yet. Shall I teach you?')
end
talkState = 0
elseif msgInArray(task, msg) then
if (status + 1) <= #item then
req = readAndStoreIt('To get a better smith you should bring me ', ' piece of ', ' pieces of ', '.', item[status + 1])
selfSay(req)
talkState = 0
else
selfSay('Sorry, but currently I have no tasks for you.')
end
PHP:
end
PHP:
elseif msgInArray({'item name', 'teh name'}, msg) and talkState == 1 then
selfSay('You may smith ITEM NAME HERE at the smithing place.')
setPlayerStorageValue(cid, STORAGE_VALUE_HERE, VALUE_HERE_DIFFERENT_FOR_DIFFERENT_ITEMS1)
talkState = 0
elseif msgInArray({'item name2', 'teh name2'}, msg) and talkState == 1 then
selfSay('You may smith ITEM NAME HERE at the smithing place.')
setPlayerStorageValue(cid, STORAGE_VALUE_HERE, VALUE_HERE_DIFFERENT_FOR_DIFFERENT_ITEMS2)
talkState = 0
elseif msgInArray({'item name3', 'teh name3'}, msg) and talkState == 1 then
selfSay('You may smith ITEM NAME HERE at the smithing place.')
setPlayerStorageValue(cid, STORAGE_VALUE_HERE, VALUE_HERE_DIFFERENT_FOR_DIFFERENT_ITEMS3)
talkState = 0
PHP:
function onUse(cid, item, frompos, item2, topos)
if item.uid == 1337 and item.itemid == 1945 then
smith(ITEMS[1], {x=85, y=28, z=9}, {x=85, y=27, z=9}, {x=85, y=29, z=9}, 2408, 1)
doTransformItem(item.uid, item.itemid+1)
elseif item.uid == 1337 and item.itemid == 1946 then
doTransformItem(item.uid, item.itemid-1)
end
end
PHP:
smith(ITEMS[1], {x=85, y=28, z=9}, {x=85, y=27, z=9}, {x=85, y=29, z=9}, 2408, 1)
doTransformItem(item.uid, item.itemid+1)
PHP:
if getPlayerStorageValue(cid, STORAGE_VALUE_HERE) == VALUE_HERE_DIFFERENT_FOR_DIFFERENT_ITEMS1 then
smith(ITEMS[1], {x=85, y=28, z=9}, {x=85, y=27, z=9}, {x=85, y=29, z=9}, 2408, 1)
elseif getPlayerStorageValue(cid, STORAGE_VALUE_HERE) == VALUE_HERE_DIFFERENT_FOR_DIFFERENT_ITEMS2 then
smith(ITEMS[2], {x=85, y=28, z=9}, {x=85, y=27, z=9}, {x=85, y=29, z=9}, 2408, 1)
elseif getPlayerStorageValue(cid, STORAGE_VALUE_HERE) == VALUE_HERE_DIFFERENT_FOR_DIFFERENT_ITEMS3 then
smith(ITEMS[3], {x=85, y=28, z=9}, {x=85, y=27, z=9}, {x=85, y=29, z=9}, 2408, 1)
end