Grimekk
memsoria.pl
- Joined
- Oct 9, 2011
- Messages
- 609
- Reaction score
- 55
Poradnik poni?ej jest po prostu list? skrypt?w kt?re mog? by? zoptymalizowane po przez ich skr?cenie. Nie b?d? t?umaczy? dzia?ania ka?dego z kod?w, bo zaj??oby to po prostu wieczno??. Je?li ju? wiesz czego szukasz to powiniene? wiedzie? jak to dzia?a. Zaczynajmy.
Zamiast pisania tej instrukcji w ten spos?b:
[lua]
//zle
x = 7
if x < 10 then
x = 10
end[/lua]
Mo?na to zrobi? w ten:
[lua]
//dobrze
x = 7
x = math.max(x, 10)[/lua]
Tak samo zreszt? z tym:
[lua]
//zle
x = 23
if x > 20 then
x = 20
end[/lua]
[lua]//dobrze
x = 23
x = math.min(x, 20)[/lua]
A je?eli chcia?by? oba z??czy?, to nie piszemy tego:
[lua]
//zle
x = 23
if x < 10 then
x = 10
elseif x > 20 then
x = 20
end[/lua]
Tylko to:
[lua]
//dobrze
x = 23
x = math.min(math.max(x, 10), 20)[/lua]
Lub:
[lua]
//dobrze
x = 23
x = math.max(math.min(x, 20), 10)[/lua]
Funkcja math.min zwraca nam najni?sz? warto??, za? math.max najwy?sz?.
Nast?pna optymalizacja mo?e nast?pi? w tym skrypcie:
[lua]
//zle
if x == 10 then
y = 100
b = 50
xybz = x + y + b + 35
elseif x == 20 then
y = 100
b = 50
xybz = x + y + b + 110
else
y = 30
b = 50
xybz = x + y + b + 20
end[/lua]
Mo?e by? on skr?cony do:
[lua]
//dobrze
y = 100
b = 50
if x == 10 then
z = 35
elseif x == 20 then
z = 110
else
y = 30
z = 20
end
xybz = x + y + b + z[/lua]
Kolejnym b??dnym kodem b?dzie to:
[lua]
//zle
if x == 10 then
y = 100
b = 50
xybz = x + y + b + 35
elseif x == 20 then
y = 40
b = 78
xybz = x + y + b + 76
elseif x == 30 then
y = 80
b = 50
xybz = x + y + b + 45
elseif x == 40 then
y = 100
b = 666
xybz = x + y + b + 144
elseif x == 50 then
y = 33
b = 45
xybz = x + y + b + 12[/lua]
Wersja poprawna:
[lua]
//dobrze
function numbers(x, y, b, z)
return (x + y + b + z)
end
if x == 10 then
xybz = numbers(x, 100, 50, 35)
elseif x == 20 then
xybz = numbers(x, 40, 78, 76)
elseif x == 30 then
xybz = numbers(x, 80, 50, 45)
elseif x == 40 then
xybz = numbers(x, 100, 666, 144)
elseif x == 50 then
xybz = numbers(x, 33, 45, 12)
else
xybz = numbers(x, 100, 100, 20)
end[/lua]
Lub jeszcze kr?cej:
[lua]
//dobrze
results = {
[10] = {100, 50, 35},
[20] = {40, 78, 76},
[30] = {80, 50, 45},
[40] = {100, 666, 144},
[50] = {33, 45, 12},
default = {100, 100, 20}
}
result = results[x] or results.default
xybz = x + result[1] + result[2] + result[3][/lua]
A zamiast tego:
[lua]
//zle
doSummonCreature("Rat", pos)
doSummonCreature("Rat", pos)
doSummonCreature("Rat", pos)
doSummonCreature("Troll", pos)
doSummonCreature("Troll", pos)
doSummonCreature("Orc", pos)[/lua]
Mo?emy po prostu doda? p?tle. Skrypt wtedy b?dzie wygl?da? nast?puj?co:
[lua]
//dobrze
local summons = {["Rat"] = 3, ["Troll"] = 2, ["Orc"] = 1}
for k, v in pairs(summons) do
for i=1, v do
doSummonCreature(k, pos)
end
end[/lua]
Tutaj kolejny za d?ugi skrypt kt?ry b?dzie nam dawa? addony:
[lua]
//zle
sexAddons = {
{[136]=142, [147]=150, [155]=158, [252]=252},
{[128]=134, [143]=146, [151]=154, [251]=251}
}
local addons = sexAddons[getPlayerSex(cid)+1]
if (addons ~= nil) then
for k, v in pairs(addons) do
for i=k, v do
doPlayerAddOutfit(player, i, addonType[1])
end
end
end[/lua]
A w tej sytuacji wystarczy zrobi? tylko to!:
[lua]
//dobrze
numbers = {
[10] = 30,
[55] = 65,
[80] = 140
}
for start, stop in pairs(numbers) do
for number=start, stop do
print(number)
end
end[/lua]
Jednym z kolejnych b??d?w podczas pisania kodu jest dodawanie nil'a - a jest on po prostu zb?dny. Mo?na to zobaczy? na przyk?adzie poni?ej:
[lua]//zle
function doSomething(x)
if x == nil then
x = 1
end
return x
end[/lua]
[lua]
//dobrze
function doSomething(x)
return x or 1
end[/lua]
Co tu si? sta?o? Solucja problemu jest bardzo prosta. Je?eli x = nil, lub false to po prostu bierze nast?pn? warto??.
Jeszcze wi?ksze skr?cenie:
[lua]
//dobrze
x = 5
y = 10
z = x or y or 5[/lua]
Tu za? skrypt najpierw sprawdza czy x = nil. Je?eli tak, to p??niej sprawdza czy y = nil. Teraz gdy oba = nil, to skrypt po prostu zamienia z w 5.
Kolejny przyk?ad kt?ry nigdy nie zwr?ci nil'a:
[lua]
//dobrze
function sum(a, b)
return (a or 0) + (b or 0)
end[/lua]
W praktyce to wygl?da tak:
[lua]print(sum(5, 10))
print(sum(5, nil))
print(sum(nil, 10))
print(sum(5))[/lua]
Powy?szy skrypt zwr?ci nam to:
A je?li chcesz wiadomo?? kt?ra wysy?a error to zamiast tego:
[lua]
//zle
if x == nil then
if y == nil then
print("Error, all values are nil!")
else
z = y
end
else
z = x
end[/lua]
Wpisz to:
[lua]
//prawie dobrze
z = x or y or print("Error, all values are nil")[/lua]
Teraz, gdy x = nil, z zamieni si? w y, a je?eli y = nil to silnik wy?le wiadomo?? "Error, all values are nil", ale z zamieni si? w nil. Co zatem zrobi? aby wys?a? wiadomo?? i nada? z warto???
Sp?jrz:
[lua]
//dobrze
z = x or y or print("Error, all values are nil") or 0[/lua]
Dzi?ki dodaniu "or 0", silnik wy?le wiadomo?? i z = 0!
Tutaj mamy kolejny przyk?ad u?ywania "or":
[lua]
//zle
function onSay(cid, words, param)
param = tonumber(param)
vocations = {"Sorcerer", "Druid", "Paladin", "Knight", "Master Sorcerer", "Elder Druid", "Royal Paladin", "Elite Knight"}
if vocations[param] ~= nil then
vocation = vocations[param]
else
vocation = "Unknown"
end
end[/lua]
Poprawnie:
[lua]
//dobrze
function onSay(cid, words, param)
param = tonumber(param)
vocations = {"Sorcerer", "Druid", "Paladin", "Knight", "Master Sorcerer", "Elder Druid", "Royal Paladin", "Elite Knight"}
vocation = vocations[param] or "Unknown"
end[/lua]
Je?eli chcesz sprawdzi? czy kilka zmiennych razem = nil, robisz to w ten spos?b:
[lua]
//zle
if x and y and z then
pos = {x=x, y=y, z=z}
end[/lua]
a przecie? to samo mo?na zrobi? o tak:
[lua]
//dobrze
(a and b) or (c and d) or e[/lua]
"(a and b)" zwraca b je?li nie jest nil'em.
Czyli to:
[lua]
//dobrze
result = (a and b) or (c and d) or e[/lua]
To to samo co to:
[lua]
//zle
if a then
result = b
elseif c then
result = d
else
result = e
end[/lua]
Gdy u?ywasz tonumber zapewne piszesz skrypty w ten spos?b:
[lua]function position(x, y, z, stackpos)
if ((x and y and z) and type(tonumber(x..y..z)) == 'number') then
pos = {x=x, y=y, z=z}
if (stackpos and type(stackpos) == 'number') then
pos.stackpos = stackpos
end
return pos
end
return false
end[/lua]
Jak wida? to:
[lua]
//zle
type(tonumber(x) == 'number' and type(tonumber
== 'number' and type(tonumber(z) == 'number'[/lua]
To po prostu inna wersja tego:
[lua]
//dobrze
type(tonumber(x..y..z)) == 'number'[/lua]
Jak to si? sta?o? Przyk?ad:
[lua]x = "134"
y = "abc"
z = "7"
print(tonumber(x))
print(tonumber
)
print(tonumber(z))
print(tonumber(x..y..z))[/lua]
Rezultatem tego skryptu b?dzie:
Dlaczego? Bo tonumber tylko akceptuje znaki numeryczne. Wi?c je?li u?ywasz tonumber do tekstu, nawet je?li posiada on gdzie? numer to skrypt i tak zwr?ci nil.
Zamiast tego d?ugiego skryptu:
[lua]
//zle
if (x > z) then
r = x
else
r = z
end [/lua]
Mo?na napisa? to:
[lua]
//dobrze
r = (x > z and x) or z[/lua]
Co to jest? Tak jak m?wi?em, gdy wpisujesz co? typu "1 and 2 and 3" to zwr?ci nam ostatni? warto??, w tym wypadku 3. Dlatego te? pisz? "x > z", bo gdy warunek si? spe?ni to skrypt doda te? "and x", co zamienia ostatni? warto?? w x przy okazji transformuj?c r tak?e w x. Ale gdy "x > z" wychodzi false, to skrypt przejdzie do "or z" co zmienia r w z.
Kolejny przyk?ad:
[lua]
//zle
if (type(x) == "number" and type
== "number") then
r = math.max(x, y)
else
r = 0
end[/lua]
[lua]
//dobrze
r = (type(x) == "number" and type
== "number" and math.max(x, y)) or 0[/lua]
Lub troch? bardziej zaawansowanie:
[lua]
//zle
if (type(x) == "number" and type
== "number") then
r = math.max(x, y)
elseif (type(x) == "number") then
r = x
elseif (type
== "number") then
r = y
else
r = 0
end[/lua]
Mo?na skrypt przetransformowa? w to:
[lua]
//zle
r = (type(x) == "number" and type
== "number" and math.max(x, y)) or (type(x) == "number" and x) or (type
== "number" and y) or 0[/lua]
Jak wida? da?em tu przypis "//zle", a to dlatego, ?e kod jest przynajmniej dla mnie nieczytelny i nie polecam u?ywania tej metody, chocia? sama wiedza nt. takiej techniki si? Wam przyda.
Poradnik pisany z pomoc? tutoriala z otland'u. Zabraniam jego kopiowania na inne strony - zosta? on napisany dla www.tibia.net.pl.
Zamiast pisania tej instrukcji w ten spos?b:
[lua]
//zle
x = 7
if x < 10 then
x = 10
end[/lua]
Mo?na to zrobi? w ten:
[lua]
//dobrze
x = 7
x = math.max(x, 10)[/lua]
Tak samo zreszt? z tym:
[lua]
//zle
x = 23
if x > 20 then
x = 20
end[/lua]
[lua]//dobrze
x = 23
x = math.min(x, 20)[/lua]
A je?eli chcia?by? oba z??czy?, to nie piszemy tego:
[lua]
//zle
x = 23
if x < 10 then
x = 10
elseif x > 20 then
x = 20
end[/lua]
Tylko to:
[lua]
//dobrze
x = 23
x = math.min(math.max(x, 10), 20)[/lua]
Lub:
[lua]
//dobrze
x = 23
x = math.max(math.min(x, 20), 10)[/lua]
Funkcja math.min zwraca nam najni?sz? warto??, za? math.max najwy?sz?.
Nast?pna optymalizacja mo?e nast?pi? w tym skrypcie:
[lua]
//zle
if x == 10 then
y = 100
b = 50
xybz = x + y + b + 35
elseif x == 20 then
y = 100
b = 50
xybz = x + y + b + 110
else
y = 30
b = 50
xybz = x + y + b + 20
end[/lua]
Mo?e by? on skr?cony do:
[lua]
//dobrze
y = 100
b = 50
if x == 10 then
z = 35
elseif x == 20 then
z = 110
else
y = 30
z = 20
end
xybz = x + y + b + z[/lua]
Kolejnym b??dnym kodem b?dzie to:
[lua]
//zle
if x == 10 then
y = 100
b = 50
xybz = x + y + b + 35
elseif x == 20 then
y = 40
b = 78
xybz = x + y + b + 76
elseif x == 30 then
y = 80
b = 50
xybz = x + y + b + 45
elseif x == 40 then
y = 100
b = 666
xybz = x + y + b + 144
elseif x == 50 then
y = 33
b = 45
xybz = x + y + b + 12[/lua]
Wersja poprawna:
[lua]
//dobrze
function numbers(x, y, b, z)
return (x + y + b + z)
end
if x == 10 then
xybz = numbers(x, 100, 50, 35)
elseif x == 20 then
xybz = numbers(x, 40, 78, 76)
elseif x == 30 then
xybz = numbers(x, 80, 50, 45)
elseif x == 40 then
xybz = numbers(x, 100, 666, 144)
elseif x == 50 then
xybz = numbers(x, 33, 45, 12)
else
xybz = numbers(x, 100, 100, 20)
end[/lua]
Lub jeszcze kr?cej:
[lua]
//dobrze
results = {
[10] = {100, 50, 35},
[20] = {40, 78, 76},
[30] = {80, 50, 45},
[40] = {100, 666, 144},
[50] = {33, 45, 12},
default = {100, 100, 20}
}
result = results[x] or results.default
xybz = x + result[1] + result[2] + result[3][/lua]
A zamiast tego:
[lua]
//zle
doSummonCreature("Rat", pos)
doSummonCreature("Rat", pos)
doSummonCreature("Rat", pos)
doSummonCreature("Troll", pos)
doSummonCreature("Troll", pos)
doSummonCreature("Orc", pos)[/lua]
Mo?emy po prostu doda? p?tle. Skrypt wtedy b?dzie wygl?da? nast?puj?co:
[lua]
//dobrze
local summons = {["Rat"] = 3, ["Troll"] = 2, ["Orc"] = 1}
for k, v in pairs(summons) do
for i=1, v do
doSummonCreature(k, pos)
end
end[/lua]
Tutaj kolejny za d?ugi skrypt kt?ry b?dzie nam dawa? addony:
[lua]
//zle
sexAddons = {
{[136]=142, [147]=150, [155]=158, [252]=252},
{[128]=134, [143]=146, [151]=154, [251]=251}
}
local addons = sexAddons[getPlayerSex(cid)+1]
if (addons ~= nil) then
for k, v in pairs(addons) do
for i=k, v do
doPlayerAddOutfit(player, i, addonType[1])
end
end
end[/lua]
A w tej sytuacji wystarczy zrobi? tylko to!:
[lua]
//dobrze
numbers = {
[10] = 30,
[55] = 65,
[80] = 140
}
for start, stop in pairs(numbers) do
for number=start, stop do
print(number)
end
end[/lua]
Jednym z kolejnych b??d?w podczas pisania kodu jest dodawanie nil'a - a jest on po prostu zb?dny. Mo?na to zobaczy? na przyk?adzie poni?ej:
[lua]//zle
function doSomething(x)
if x == nil then
x = 1
end
return x
end[/lua]
[lua]
//dobrze
function doSomething(x)
return x or 1
end[/lua]
Co tu si? sta?o? Solucja problemu jest bardzo prosta. Je?eli x = nil, lub false to po prostu bierze nast?pn? warto??.
Jeszcze wi?ksze skr?cenie:
[lua]
//dobrze
x = 5
y = 10
z = x or y or 5[/lua]
Tu za? skrypt najpierw sprawdza czy x = nil. Je?eli tak, to p??niej sprawdza czy y = nil. Teraz gdy oba = nil, to skrypt po prostu zamienia z w 5.
Kolejny przyk?ad kt?ry nigdy nie zwr?ci nil'a:
[lua]
//dobrze
function sum(a, b)
return (a or 0) + (b or 0)
end[/lua]
W praktyce to wygl?da tak:
[lua]print(sum(5, 10))
print(sum(5, nil))
print(sum(nil, 10))
print(sum(5))[/lua]
Powy?szy skrypt zwr?ci nam to:
Code:
15
5
10
5
[lua]
//zle
if x == nil then
if y == nil then
print("Error, all values are nil!")
else
z = y
end
else
z = x
end[/lua]
Wpisz to:
[lua]
//prawie dobrze
z = x or y or print("Error, all values are nil")[/lua]
Teraz, gdy x = nil, z zamieni si? w y, a je?eli y = nil to silnik wy?le wiadomo?? "Error, all values are nil", ale z zamieni si? w nil. Co zatem zrobi? aby wys?a? wiadomo?? i nada? z warto???
Sp?jrz:
[lua]
//dobrze
z = x or y or print("Error, all values are nil") or 0[/lua]
Dzi?ki dodaniu "or 0", silnik wy?le wiadomo?? i z = 0!
Tutaj mamy kolejny przyk?ad u?ywania "or":
[lua]
//zle
function onSay(cid, words, param)
param = tonumber(param)
vocations = {"Sorcerer", "Druid", "Paladin", "Knight", "Master Sorcerer", "Elder Druid", "Royal Paladin", "Elite Knight"}
if vocations[param] ~= nil then
vocation = vocations[param]
else
vocation = "Unknown"
end
end[/lua]
Poprawnie:
[lua]
//dobrze
function onSay(cid, words, param)
param = tonumber(param)
vocations = {"Sorcerer", "Druid", "Paladin", "Knight", "Master Sorcerer", "Elder Druid", "Royal Paladin", "Elite Knight"}
vocation = vocations[param] or "Unknown"
end[/lua]
Je?eli chcesz sprawdzi? czy kilka zmiennych razem = nil, robisz to w ten spos?b:
[lua]
//zle
if x and y and z then
pos = {x=x, y=y, z=z}
end[/lua]
a przecie? to samo mo?na zrobi? o tak:
[lua]
//dobrze
(a and b) or (c and d) or e[/lua]
"(a and b)" zwraca b je?li nie jest nil'em.
Czyli to:
[lua]
//dobrze
result = (a and b) or (c and d) or e[/lua]
To to samo co to:
[lua]
//zle
if a then
result = b
elseif c then
result = d
else
result = e
end[/lua]
Gdy u?ywasz tonumber zapewne piszesz skrypty w ten spos?b:
[lua]function position(x, y, z, stackpos)
if ((x and y and z) and type(tonumber(x..y..z)) == 'number') then
pos = {x=x, y=y, z=z}
if (stackpos and type(stackpos) == 'number') then
pos.stackpos = stackpos
end
return pos
end
return false
end[/lua]
Jak wida? to:
[lua]
//zle
type(tonumber(x) == 'number' and type(tonumber
To po prostu inna wersja tego:
[lua]
//dobrze
type(tonumber(x..y..z)) == 'number'[/lua]
Jak to si? sta?o? Przyk?ad:
[lua]x = "134"
y = "abc"
z = "7"
print(tonumber(x))
print(tonumber
print(tonumber(z))
print(tonumber(x..y..z))[/lua]
Rezultatem tego skryptu b?dzie:
Code:
134
nil
7
nil
Zamiast tego d?ugiego skryptu:
[lua]
//zle
if (x > z) then
r = x
else
r = z
end [/lua]
Mo?na napisa? to:
[lua]
//dobrze
r = (x > z and x) or z[/lua]
Co to jest? Tak jak m?wi?em, gdy wpisujesz co? typu "1 and 2 and 3" to zwr?ci nam ostatni? warto??, w tym wypadku 3. Dlatego te? pisz? "x > z", bo gdy warunek si? spe?ni to skrypt doda te? "and x", co zamienia ostatni? warto?? w x przy okazji transformuj?c r tak?e w x. Ale gdy "x > z" wychodzi false, to skrypt przejdzie do "or z" co zmienia r w z.
Kolejny przyk?ad:
[lua]
//zle
if (type(x) == "number" and type
r = math.max(x, y)
else
r = 0
end[/lua]
[lua]
//dobrze
r = (type(x) == "number" and type
Lub troch? bardziej zaawansowanie:
[lua]
//zle
if (type(x) == "number" and type
r = math.max(x, y)
elseif (type(x) == "number") then
r = x
elseif (type
r = y
else
r = 0
end[/lua]
Mo?na skrypt przetransformowa? w to:
[lua]
//zle
r = (type(x) == "number" and type
Jak wida? da?em tu przypis "//zle", a to dlatego, ?e kod jest przynajmniej dla mnie nieczytelny i nie polecam u?ywania tej metody, chocia? sama wiedza nt. takiej techniki si? Wam przyda.
Poradnik pisany z pomoc? tutoriala z otland'u. Zabraniam jego kopiowania na inne strony - zosta? on napisany dla www.tibia.net.pl.