LINUX.ORG.RU

Предсказуемость математики и луа

 ,


1

1
function hashStr (nome)
	hours, minutes = GetGameTime()
	count1=hours* 3,1415926535
	count2=minutes* 3,1415926535
	count3=count1*count2
	count3=string.sub(count3, 1, 3)
	count3=string.format("%03d",count3)
	hNik=string.byte(nome,1)
	hNik2=string.byte(nome,2)
	hNome=hNik*hNik2
	hNome=string.sub(hNome, 1, 3)
	hNome=string.format("%03d",hNome)
	r1=string.sub(count3, 1, 1)
	r2=string.sub(hNome, 1, 1)
	r3=string.sub(count3, 2, 2)
	r4=string.sub(hNome, 2, 2)
	r5=string.sub(count3, 3, 3)
	r6=string.sub(hNome, 3, 3)
	r=r1 .. r2 .. r3 .. r4 .. r5 .. r6
	return r
end

hours, minutes = GetGameTime() получает текущие час и минуту в формате: 01 22

Скармливаем слово на одном компе - получаем предсказуемо одинаковый результат. Скармливаем на другом компе получаем тоже предсказуемо одинаковый результат, но не такой, как на предыдущем компе. Это как вообще? Данные одинаковые. Ник один и тот же. Время одно и то же. Результат всегда разный. Это вообще законно?! Время возвращается серверное - одинаковое и там и там.

Перемещено Dimez из general

★★★★★

Последнее исправление: hobbit (всего исправлений: 2)

Ответ на: комментарий от LightDiver

Просто переписываем функцию

Ну, собственно, да. Именно поэтому бэкенды веб-приложений никогда не доверяют тому, что им присылает фронтенд и валидируют все присланное самостоятельно — потому что пользователь может с кодом фронтенда делать все, что ему заблагорассудится.

Клиентская часть аддона точно так же полностью во власти пользователя, поэтому ты не можешь доверять тому, что она тебе присылает, хэш там или не хэш. Для проверки присланного на вшивость нужен доверенный источник информации, не подконтрольный пользователю (например, база данных для веб-приложения или сервер ВоВ для твоего аддона).

Собственно, у пользователя ничего спрашивать и не нужно будет, получил запрос на награду @ проверил ачивки на сервере @ послал дальше охотиться на зайцев.

Правда, я не уверен, что это реализуемо на практике, как я вижу, даже на официальных серверах люди ходят парсить какие-то сторонние сайты с игровой статистикой для этого.

Nervous ★★★★★
()
Ответ на: комментарий от Nervous

Тут вся сложность в том, что ворлд оф варкрафт по моим ощущениям проектировалась как синглплеерная игра. В ней плохо все, что связано с сообщением между игроками. Вообще все. Начиная с гильдий. Такое ощущение, что это привязано сбоку временная приблуда на отвали.

Не исключение - достижения. Ты не можешь спросить про них у сервера. Это может сделать только сам персонаж. И так во всем. Поэтому приходится хоть как то выкручиваться и импровизировать.

Вот реализую текстовые квесты и посмотрим насколько это будет удачно. По крайней мере в стиле ДнД в ручном режиме игрокам нравится. Там не считеришь.

Вообще я как открыл для себя луа, столько идей интересных. Хз за что браться. Кидаюсь во все стороны разом. Хоть один тип квестов доделал до конца и хорошо уже.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

Не исключение - достижения. Ты не можешь спросить про них у сервера. Это может сделать только сам персонаж.

Что странно, ибо зачем еще достижения, если не размахивать ими перед другими.

Nervous ★★★★★
()
Ответ на: комментарий от Nervous

Ну, ты можешь размахивать перед другими. Но ты сам вручную. То есть ты можешь линкануть свою ачивку в чат.

А другие удаленно твой прогресс получить не могут. Там вообще с мультиплеером все очень тяжко. Я бы мог рассказать про устройство гильдий, но тогда будет очень много мата. И с каждой новой версией все это только урезали и отключали.

Вообще чужой прогресс можно глянуть технически. Но для этого нужно подойти вплотную к персонажу и открыть длинный список сравнения твоего прогресса с его прогрессом. И пока ты смотришь, нужно чтобы он не сбежал от тебя.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 3)
Ответ на: комментарий от LINUX-ORG-RU

Насчет вот этой функции. Кажись я чего то упускаю. Хм. Смотри. Повторил я ее немного изменив:

https://pastebin.com/QjWY0JUz

--[[ Создание фрейма, который будет содержать текстуру иконки
iconFrame1 = CreateFrame("FRAME", "myAddonIconFrame", WorldMapFrame)
iconFrame1:SetSize(12, 12)
iconFrame1.iconTexture = iconTexture1
iconFrame1:SetScript("OnMouseUp", function() print("Clicked on myAddon icon!") end)

-- Создание текстуры иконки
iconTexture1 = iconFrame:CreateTexture("myAddonIcon", "OVERLAY")
iconTexture1:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
iconTexture1:SetSize(12, 12)
iconTexture1:SetPoint("CENTER", 110, 110)
-- Установка позиции фрейма на карте/миникарте
iconFrame1:SetHeight(12)
iconFrame1:SetWidth(12)
-- Показ фрейма на карте/миникарте
iconFrame1:Show()
--]]
iconRis={}
iconRisText={}
function iconRis:configure(id,razmerX,razmerY,iconText)
	self[id] = CreateFrame("FRAME", "myAddonIconFrame", WorldMapFrame)
	self[id]:SetSize(razmerX, razmerY)
	self[id].iconTexture = iconText
	self[id]:SetScript("OnMouseUp", function() print("Clicked on myAddon icon!") end)
	self[id]:Show()
end

function iconRisText:configure(id,razmerX,razmerY,X,Y)
	self[id] = iconRis[id]:CreateTexture("myAddonIcon", "OVERLAY")
	self[id]:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
	self[id]:SetSize(razmerX, razmerY)
	self[id]:SetPoint("CENTER", X, Y)
	self[id]:SetHeight(razmerX)
	self[id]:SetWidth(razmerY)
end

iconRis:configure(1,24,24,iconRisText[1])
iconRisText:configure(1,24,24,111,111)
iconRis[1]:Show()
iconRisText[1]:Show()

Закомментированный код пашет и рисует иконку. А то что в функции нет. Не понимать. Вроде все же сделал так же.

Я даже заполнил данные для теста вручную:

iconRis={}
iconRisText={}
function iconRis:configure(idI,razmerXI,razmerYI,iconTextI)
	self[1] = CreateFrame("FRAME", "myAddonIconFrame", WorldMapFrame)
	self[1]:SetSize(12, 12)
	self[1].iconTexture = iconRisText[1]
	self[1]:Show()
end

function iconRisText:configure(idT,razmerXT,razmerYT,XT,YT)
	self[1] = iconRis[1]:CreateTexture("myAddonIcon", "OVERLAY")
	self[1]:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
	self[1]:SetSize(12, 12)
	self[1]:SetPoint("CENTER", 110, 110)
	self[1]:SetHeight(12)
	self[1]:SetWidth(12)
end

iconRis:configure(1,24,24,iconRisText[1])
iconRisText:configure(1,24,24,111,111)
iconRis[1]:Show()
iconRisText[1]:Show()

Нифига не пашет. Значит что то не так с функциями.. Хм.

Конкретно баг вот тут:

	self[id] = iconRis[id]:CreateTexture("myAddonIcon", "OVERLAY")

Если я подставляю обычное имя фрейма, работает, а если из функции, то нет. Где я дурак? iconRis[id] <—

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

У меня в голове сейчас туман, но на первый взгляд вроде

-iconRis:configure(1,24,24,iconRisText[1])
-iconRisText:configure(1,24,24,111,111)
+iconRisText:configure(1,24,24,111,111)
+iconRis:configure(1,24,24,iconRisText[1])

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Забей. Тут мне прислали код от гпт очень кривой, я его поправил тоже криво до полу-рабочего состояния. Так что сейчас лучше попробую переписать все с нуля типа правильно, а потом оформлять в функцию. Там половина строк оказывается кривые и не нужны.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

Тут мне прислали код от гпт очень кривой

Эммм, ты мне код от ГПТ для правки даёшь? Ты его не сам писал? Выше ты передавал таблицу которую инициализировал после того как её передал. Пустую передавал. Вот оно и не работало

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Сам писал. Смотри последовательность событий. Пару недель назад я пытался найти как создавать иконки на карте. Нихера не выходило. Я кинул клич в гильдию. Мне скинули кусок кода, который не работал. Я этот кусок думал, менял, довел до полурабочего состояния. Потом на его основе работал с иконками.

В принципе все работало, пока я не попытался оформить работу в виде функций в итоге с иконками. Оказалось, что несколько строк там не нужны. Как то так. Сейчас пытаюсь сделать правильно. Ибо за это время в принципе понял что не так.

В принципе я его уже переделал:

iconFrame1 = CreateFrame("FRAME", "myAddonIconFrame", WorldMapFrame)
iconFrame1:SetSize(12, 12)
iconFrame1:SetPoint("BOTTOMLEFT")
-- Создание текстуры иконки
iconTexture1 = iconFrame1:CreateTexture("myAddonIcon", "OVERLAY")
iconTexture1:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
iconTexture1:SetSize(12, 12)
iconTexture1:SetPoint("BOTTOMLEFT", 0, 0)

iconFrame1:Show()

Вот правильный вариант создания иконок. Мусор вычистил, теперь можно и дальше работать.

Понимаешь, мне нужен был сам принцип создания иконок и размещения на карте. И я его получил. Дальше можно с этим уже работать.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

В любом случае выше ты сначала пустую iconRisText передавал в iconRis:configure и только потом вызывал iconRisText:configure тут ты хоть всё идеально сделай работать не будет. Код может и верный, а порядок вызова функций нет =)

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Я сейчас попробую правильно. Секунду. Я кажется понял как.

Наверное вот так:

-- Создание фрейма, который будет содержать текстуру иконки
iconFrame1 = CreateFrame("FRAME", "myAddonIconFrame", WorldMapFrame)
iconFrame1:SetSize(12, 12)
iconFrame1:SetPoint("BOTTOMLEFT")
-- Создание текстуры иконки
iconTexture1 = iconFrame1:CreateTexture("myAddonIcon", "OVERLAY")
iconTexture1:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
iconTexture1:SetSize(12, 12)
iconTexture1:SetPoint("BOTTOMLEFT", 0, 0)

iconFrame1:Show()

iconRis={}
iconRisText={}

function iconRis:configure(id,x,y)
	self[id] = CreateFrame("FRAME", "myAddonIconFrame", WorldMapFrame)
	self[id]:SetSize(Rx, Ry)
	self[id]:SetPoint("BOTTOMLEFT")
end

function iconRisText:configure(id,Rx,Ry,x,y)
	self[id] = iconRis[id]:CreateTexture("myAddonIcon", "OVERLAY")
	self[id]:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
	self[id]:SetSize(Rx, Ry)
	self[id]:SetPoint("BOTTOMLEFT", x, y)
end

`
LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

ХА! Работает! Блин, я просто не мог понять назначения пары строк в коде….потому что у тех строк не было назначения. Это был мусор. Теперь полностью разобрался как эта срань работает. И спасибо за функцию, она охренительна.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

Тыб код вот так оформлял, с подсветкой то повеселее читать.

```lua
-- Создание фрейма, который будет содержать текстуру иконки
function iconRis:configure(id,x,y)
	self[id] = CreateFrame("FRAME", "myAddonIconFrame", WorldMapFrame)
	self[id]:SetSize(Rx, Ry)
	self[id]:SetPoint("BOTTOMLEFT")
end

function iconRisText:configure(id,Rx,Ry,x,y)
	self[id] = iconRis[id]:CreateTexture("myAddonIcon", "OVERLAY")
	self[id]:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
	self[id]:SetSize(Rx, Ry)
	self[id]:SetPoint("BOTTOMLEFT", x, y)
end
```
-- Создание фрейма, который будет содержать текстуру иконки
function iconRis:configure(id,x,y)
	self[id] = CreateFrame("FRAME", "myAddonIconFrame", WorldMapFrame)
	self[id]:SetSize(Rx, Ry)
	self[id]:SetPoint("BOTTOMLEFT")
end

function iconRisText:configure(id,Rx,Ry,x,y)
	self[id] = iconRis[id]:CreateTexture("myAddonIcon", "OVERLAY")
	self[id]:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
	self[id]:SetSize(Rx, Ry)
	self[id]:SetPoint("BOTTOMLEFT", x, y)
end
LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Ну не могу я не похвастатьс. Смотри для чего в том числе все это было:

https://cdn.discordapp.com/attachments/811217303378329643/1100486206594240522/WoWScrnShot_042623_011903.jpg

Раз.

https://cdn.discordapp.com/attachments/811217303378329643/1100493656525394002/WoWScrnShot_042623_014842.jpg

Два.

На первом скрине вон та полоска сверху карты состоит из 1024 иконок. Полное изображение карты из кусков занимает 4096 иконок. Так то.

На втором блок иконок 16х16. Ну круто же?

Пишем функцию вывода таких блоков и выводим их когда надо. В функцию сигнал - скрыть или показать.

И в итоге мы можем рисовать на карте что угодно для игроков. И в любой момент выводить.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

Прикольно, да с таблом на которое можно выводить что угодно можно много что придумать.

Когда своё и работает эт клёва =) Вернее клёва когда работает сначала в голове, а потом в реальности. А какое то время назад ты за таким только наблюдать мог =)

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Смотри. Вот я нащупал рабочий вариант функции допустим:

function mostraKrtM1x1(signalKrt)
	jj=20
	j=394
	if signalKrt=="Show" then
		for i=0,16 do
			iconRis:configure(i,545,350)
			iconRisText:configure(i,9.1,6,0,0,i)
			iconRis[i]:SetPoint("BOTTOMLEFT", jj, j)
			jj=jj+9.1
		end
	end
	if signalKrt=="Hide" then
		for i=0,16 do
			iconRis[i]:Hide()
			iconRisText[i]:Hide()
		end
	end
end

А без ифов никак нельзя?

Например вот так пишет, что сигнал nil:

function mostraKrtM1x1(signalKrt)
	jj=20
	j=394
		for i=0,16 do
			iconRis:configure(i,545,350)
			iconRisText:configure(i,9.1,6,0,0,i)
			iconRis[i]:SetPoint("BOTTOMLEFT", jj, j)
			jj=jj+9.1
			iconRis[i]:signalKrt()
			iconRisText[i]:signalKrt()
		end

	end
end
Message: Interface\AddOns\NSQC\risIcon.lua:36: attempt to call method 'signalKrt' (a nil value)
Time: 04/26/23 14:59:20
Count: 1
Stack: Interface\AddOns\NSQC\risIcon.lua:36: in function `mostraKrtM1x1'
[string "mostraKrtM1x1("Show")"]:1: in main chunk
[C]: in function `RunScript'
Interface\FrameXML\ChatFrame.lua:2048: in function `value'
Interface\FrameXML\ChatFrame.lua:4212: in function `ChatEdit_ParseText'
Interface\FrameXML\ChatFrame.lua:3799: in function `ChatEdit_SendText'
Interface\FrameXML\ChatFrame.lua:3840: in function `ChatEdit_OnEnterPressed'
[string "*:OnEnterPressed"]:1: in function <[string "*:OnEnterPressed"]:1>

Locals: signalKrt = "Show"
(for index) = 0
(for limit) = 16
(for step) = 1
i = 0
(*temporary) = nil
(*temporary) = myAddonIconFrame {
 0 = <userdata>
}
(*temporary) = "attempt to call method 'signalKrt' (a nil value)"

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver
function mostraKrtM1x1(signalKrt)
local jj=20; 
local j=394;
  for i=0,16 do
      iconRis:configure(i,545,350)
      iconRisText:configure(i,9.1,6,0,0,i)
      iconRis[i]:SetPoint("BOTTOMLEFT", jj, j)
      jj=jj+9.1
      iconRis[i][signalKrt](iconRis[i])
      iconRisText[i][signalKrt](iconRisText[i])
      --iconRis[i]:signalKrt()
      --iconRisText[i]:signalKrt()
  end
end
LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Ага, спасибо, мне уже подсказали. Очень странная конструкция, как по мне. Ведь мы в начале строки объект уже указали. И тут вдруг нам надо указывать его еще раз в скобках. Ну такое…

Первый вариант блока у меня выходи вот такой:


function mostraKrtM1x1(signalKrt)
	if signalKrt=="Show" then
		jj=20
		j=394
		for i=0,16 do
			iconRis:configure(i,545,350)
			iconRisText:configure(i,9.1,6,0,0,i)
			iconRis[i]:SetPoint("BOTTOMLEFT", jj, j)
			jj=jj+9.1
		end
		jj=20
		j=394-6
		for i=64,80 do
			iconRis:configure(i,545,350)
			iconRisText:configure(i,9.1,6,0,0,i)
			iconRis[i]:SetPoint("BOTTOMLEFT", jj, j)
			jj=jj+9.1
		end
	elseif signalKrt=="Hide" then
		for i=0,16 do
			iconRisText[i][signalKrt](iconRisText[i])
		end
		for i=64,80 do
			iconRisText[i][signalKrt](iconRisText[i])
		end
	end
end

Но это хрень. Слишком громоздко. Второй вариант такой:

function mostraKrtM11x11(signalKrt)
	if signalKrt=="Show" then
		ranges = {{1, 16}, {65, 80},{129,144},{193,208},{257,272},{321,336},{385,400},{449,464}}
		j=394
		for range,value in pairs(ranges) do
			jj=20
			for rangeT=value[1],value[2] do
				print (rangeT)
				iconRis:configure(rangeT,545,350)
				iconRisText:configure(rangeT,9.1,6,0,0,rangeT)
				iconRis[rangeT]:SetPoint("BOTTOMLEFT", jj, j)
				jj=jj+9.1
			end
			j=j-6
		end
	else

	end
end

Но я хочу через формулу. То есть высчитывать старт строки и конец строки для блоков формулой. Сейчас выходит что то вроде такого:

for i=1,8 do  print((64 * (i - 1) + 1) .. ', ' .. (64 * (i - 1) + 16)) end 

То есть начало строки (64 * (i - 1) + 1), конец строки (64 * (i - 1) + 16)

Второй блок будет идти конец строки+16 итд.. теперь я думаю как просчитать удобнее остальные блоки и как на основе этого сделать функцию.

Люто до скрежета в зубах мешает старт с единицы, а не с нуля. Это жуть.

тут еще один косяк. Если я вставляю скрытие кусков сразу в цикл, где их рисуют, это не работает. посмотри на мой первый пример. Там я скрываю отдельными циклами. Меня это нервирует. Не понимаю почему так.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 2)
Ответ на: комментарий от LightDiver
local var = { a = 42 }
--нет разницы чем является 'a', числом,строкой,таблицей или функцией
--дёрнуть можно так
print(var.a)
--дёрнуть можно так
print(var['a'])
--если бы была функцией то так
print(var['a']())

--Потому что 'var' это хеш таблица, а всё что в ней это
--строки ссылающиеся на свои значения.

--Выражения вида 
aaa:bbb()
--Это сахар к
aaa.bbb(aaa)
--И тоже самое что
aaa['bbb'](aaa)
--Разница лишь в синтаксисе доступа

И тут вдруг нам надо указывать его еще раз в скобках. Ну такое…

Ты сам именно это попросил, а потом поменял код и теперь вызывать функцию через ['funname'] нет смысла.

Люто до скрежета в зубах мешает старт с единицы, а не с нуля.

Никак оно тебе мешать не может =)

Это жуть.

Это непривычно просто, индексация арифметическая, а не адресная. Делай всё с 1чки и всё. Сам себе проблемы устраиваешь, ты в жизни количество считаешь с 1чки вот и тут так считай. То что в Си с нуля так это потому что там это логично, другие языки под это дело часто просто мимикрируют. Единственное неудобство может возникнуть это при взаимодействии Си и Луа. У тебя такого нету. Первый элемент он первый по индексу Один и циклы начинаются с Единицы, вот и всё. Да, непривычно, сам плевался. Как когда то плевался что в си с нуля и количество элементов это не число последнего индекса. А в луа именно что оно и есть. Но как сам знаешь можно и с нуля всё делать, но нужно держать в уме ньюансы, а чтобы не держать используй Одын, а не Нулъ и всё =)

По остальному не знаю, голова не варит

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Так вот оно чо.. Через точку указывается парметр таблицы. До меня только сейчас дошло это. Тьфу ты, да, удобно. А то я обычно без имен записывал все напрямую. надо поменять подход.

Ну смотри, тебе не кажется странным вот такая структура?

aaa['bbb'](aaa)

Ведь тут мы «ааа» указываем дважды.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 2)
Ответ на: комментарий от LightDiver
local struct = 
{
    var = 42;
}

function struct:mul2()
    local result = self.val * 2;
    print(result);
    return result;
end

function struct:add2()
    local result = self.val + 2;
    print(result);
    return result;
end

local command_one  = 'mul2';
local command_twoo = 'add2';


--а вот таже самая функция, в которую
--приходит command совпадающий с именем 
--функции которую нужно выполнить для исполнения
--комманды, ничего вспомогательного мы не делаем
--поэтому передаём имя комманы как ключ к запросу 
--функции которую вызываем и всё.
--Такой код у тебя был сначала когда ты хотел 
--избавится от if
function application_b(command)
    return struct[command](struct);
end

--если нам нужно сделать несколько
--вещей в зависимости от входящего 
--парамера command то от if никуда
--не уйти, ты и переделал код так что
--конструкция типа struct[command](struct);
--тут будет поросто избыточна, банально дольше писать
--Такой код у тебя стал когда ты предыдущий код переписал
--и тут уже проще, удобнее и нагляднее писать так
--
--   struct:mul2();
--
--нежели писать так
--
--   struct[command](struct);
--
function application_a(command)
    if command == 'mul2' then
      local result = struct:mul2();
      result = result + 5;
      --тут ещё какойнить код который 
      --зависит от значения command
    elseif command == 'add2' then
      struct:add2();
      local result = struct:add2();
      result = result + 10;
      --тут ещё что-то
    end
end

--Так что ничего странного тут нет, всё завист от контекста происходящего
--Ты выбираешь наиболее удобное для себя и программы и всё.
--Язык гибкий позволяет делать и так и сяк и эдак
--А уж что ты выберешь из этого это исключительно твоё дело
--Писал прям на лоре может где ошибся, но суть ты поймёшь
LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Я сейчас сдуру написал на форуме про то чем сейчас занимаюсь и спросил совета как может лучше сделать работу с картами. В итоге отписался профессиональный разработчик, с аддоном, который пилят лет 16 уже. Кинул в меня аддоном и сказал что там все примеры есть… Осталось ощущение, будто я говорящая собака, на которую с осуждением посмотрели профессора и разошлись.

Понял что не готов к общению с программистами… Я наверное лучше сам покопаюсь по шажочкам, потихоньку. Благо вычленил у него из кода одну интересную фичу. Помнишь я пилил идентификацию? Оказывается есть секретный чат для общения аддонов. Его пользователи не видят. Надо через него все команды передавать и все.. Блин, хоть перепиливай нахрен все теперь.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

Осталось ощущение, будто я говорящая собака, на которую с осуждением посмотрели профессора и разошлись.

:D Ну, а чё, матёрые луашники это тебе не хухры мухры. Короче всё как на ЛОРе =)

Я наверное лучше сам покопаюсь по шажочкам, потихоньку.

Ничего в этом такого нет, это интересно и даже мило. А то что это само по себе хобби ещё склоняет чашу весов. Я вот вопросы задаю когда совсем голова не варит уже и многократные попытки что-то сделать мало к чему приводят и нужно пояснение.

Блин, хоть перепиливай нахрен все теперь.

Перепиливай отдельные кусочки которые по твоему уж совсем не то. С нуля не надо, работаешь с кодом учись выживать с тем что есть и улучшать его изнутри. Перепиливать с нуля это значит заранее продумать архитектуру и тупо заняться ручной работой по перебиванию кода. Хотя переписывание это тоже опыт, бывает даже интересно. Всё зависит от ситуации. Делай как делаешь, но поглядывай и придумывай получше. Этот круговорот бесконечен.

Помнишь я пилил идентификацию? Оказывается есть секретный чат для общения аддонов. Его пользователи не видят. Надо через него все команды передавать и все..

Ну, ничего страшного, зато у тебя есть код который может работать даже без этого межаддоного канала и ты свои наработки сможешь применять например потом в другой игре. Цени то что пишешь даже если считаешь это мусором, рано или поздно настанет момент и не раз когда ты окажешься в той ситуации когда у тебя не будет тех механизмов к корым ты привык в каком то другом месте и ты вспомнишь что ты пилил велосипед и можно его пере использовать видоизменив. Такое на право и на лево. Ну и потренировался. Теперь используй этот чат/канал межаддонного взаимодействия и радуйся что жизнь стала проще =) Или так всё оставь, перенесёшь позже. Тут ещё тебя должна посетить мысль о том как организовывать код, подумай как бы его организовать так что-бы если что можно было бы безболезненно и без труда переключить код с твоей верификации квестов на верефикацию через спец канал связи =)

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Я начинал писать аддон вот практически сразу после тех первых скриптов. И пишу до сих пор. Каждый день по 20 часов в сутки кодинга. В середине этого срока, например, я узнал как работают функции. Каждый день я узнаю что то новое про апи и про то как работает луа. Можешь представить что я написал в первые дни и через какую жопу это работает.

Сейчас это мне нужно переделать нелинейно.

msg1=mysplit(message)
msg2=msg1[6]

Вот я читаю сообщение, разбиваю его на отдельные слова и записываю в массив. Работаю с шестым словом в массиве. Сообщения разные, в зависимости от расположения нужных слов я и работаю. Теперь мне нужно полностью сменить расопложения слов, например.

А опыт с реализацией идентификации был офигенен, да. Сам по себе.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Ппц… Я допилил. Ровно месяц разработки. Реализованы все типы и сложности простых квестов. Все работает.. Как то пусто даже стало. Надо новое пилить. 1640 строк в клиенте, 1262 строки в сервере… По ощущениям пролетели максимум пара дней.

А остановиться уже нельзя. Хочется еще и еще что то делать. И идентификация пригодилась таки. Не зря пилил.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LightDiver

Все работает.. Как то пусто даже стало. Надо новое пилить. 1640 строк в клиенте, 1262 строки в сервере… По ощущениям пролетели максимум пара дней.

А остановиться уже нельзя. Хочется еще и еще что то делать.

Ха-ха! Добро пожаловать в клуб!

wandrien ★★
()
Ответ на: комментарий от Forum0888

https://github.com/Vladgobelen/GuildChat сервер

https://github.com/Vladgobelen/NSQC клиент

К сожалению, я буквально каждую функцию, каждую возможность изучаю находу гуглением. Додумался до комментирования нормального и читаемых переменных совсем недавно.. Так что врядли можно понять что там происходит. Но в целом оно работает. Осталось пару багов с лядскими типами данных выловить. Я уже придумал даже такую конструкцию:

if testQ[myNome]["квест_лвл2"][msg1] ~= nil then
	mozhnoLiSdatChislo11=testQ[myNome]["квест_лвл2"][msg1]
else
	msg1=tostring(msg1)
	mozhnoLiSdatChislo11=testQ[myNome]["квест_лвл2"][msg1]
end
LightDiver ★★★★★
() автор топика
Ответ на: комментарий от Forum0888

Самое смешное это первая версия аддона:

https://github.com/Vladgobelen/GuildChat/blob/96037a8c1426bde701f8b2df99e6ff62116bd81f/developer.lua

Собственно это все. Весь аддон. И это было нереально круто, ибо оно работало. А выросло в итоге ппц…

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от Forum0888

Ппц… Я в очередной раз жидко обосрался. Наверное неделю любой мог иметь функции админа в аддоне по сути. лицорука

function gmTest (gmTestNome)
	for i=1,#gmList do
		if gmTestNome==gmList[i] then
			gmTestRez=true
			break
		else
			gmTestRez = nil
		end
		i=i+1
	end
	return gmTestRez
end

Вот у меня функция проверки на ГМа.

А вот собственно список ником ГМа, в виде таблицы, который оно должно сравнивать:

gmList = {
	"Витинари", -- [1]
	"Двацветок", -- [2]
	"Детрит", -- [3]
	"Хэвлок", --[4]
	"Железобетонс", --[5]
}

И я нифига не понимаю почему это не работает. Оно абсолютно на любое принятое слово возвращает true.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Ну это ж ересь! Я вообще не понимаю. Смотри:

function gmTest (gmTestNome)
	for i=1,#gmList do
		if gmTestNome==gmList[i] then
			gmTestRez = "гм"
			break
		else
			gmTestNome = nil
		end
		i=i+1
	end
	return gmTestRez
end

for i=1,#gmList do –читаем таблицу от 1 элемента до последнего. Так? Так.

if gmTestNome==gmList[i] then –если принятый ник равняется списку таблицы, то gmTestRez = «гм» –переменная равняется «гм», выйти из цикла.

else –в противном случае gmTestNome = nil переменная равняется nil.

return gmTestRez вертаем содержимое переменной. Ну логично же? Логично. А возвращает ВСЕГДА «гм». То есть по первому условию. Что не так то?! Ну где я дурак? Что угодно скорми ей, вернет по первому условию.

Я вставил принты, сравнил. Оно даже дальше первого пункта таблицы не идет. Всегда считает, что первый пункт таблицы равняется чему годно принятому. Хотя принты выводят разное.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от LightDiver

У тебя gmTestRez — глобальная переменная, и ты её задав один раз, нигде (в этом коде) не меняешь. Если один раз твоя функция выполнит gmTestRez = "гм", после этого всегда будет возвращать "гм". Не нужно использовать глобальные переменные (если не понимаешь, что делаешь), нужно настроить линтер в редакторе, или хотя бы вручную запускать luacheck и смотреть, что скажет.

Вероятно, ты хотел вместо gmTestNome = nil написать gmTestRez = nil. Но это тоже не очень, почему сразу не вернуть результат без всяких лишних переменных? Впрочем, похоже, я в игноре, и ты это не прочитаешь, хех.

Ceiling_QB ★★★★
()
Последнее исправление: Ceiling_QB (всего исправлений: 3)
Ответ на: комментарий от Nervous

Хм.. Но почему? И оно в этом случае игнорирует все пункты таблицы, кроме первого.

А, ну да. Почему читает только первый уже понимаю. Условие типа выполняется. А вот про локальность не понял. Я вроде нигде больше не использую эту переменную.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от Nervous
function gmTest (gmTestNome)
	local gmTestRez
	for i=1,#gmList do
		if gmTestNome==gmList[i] then
			gmTestRez = "гм"
			break
		end
		i=i+1
	end
	return gmTestRez
end

Вот получается рабочий вариант. Хм. Я все чаще объявляю локальность переменных в начале структуры, но часто забываю. И мне бы понять логику почему это все ломало.

LightDiver ★★★★★
() автор топика
Ответ на: комментарий от Ceiling_QB

Спасибо. Понял. Короче, старое доброе правило: обнуляйте переменные. Спасибо огромное. Если бы я в начале ее обнулил, тоже бы сработало, как я понимаю. Но лучше привыкнуть объявлять локальность. Очень хороший урок.

Я просто не заметил твой первый комментарий. Сейчас вчитываюсь.

А как это вписать результат без переменных?

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 2)
Ответ на: комментарий от LightDiver

мне бы понять логику почему это все ломало.

Потому что в случае с глобальной переменной один раз персил — всегда персил. Значение сохраняется между вызовами функции.

Но это бы не прокнуло, если б не второй баг с присваиванием не той переменной.

Nervous ★★★★★
()
Ответ на: комментарий от Nervous

Да, спасибо, мне тут уже объяснили. Я запомнил на будущее.\

Второй баг это просто опечатка. Когда оно мне начало всегда выдавать «тру», я изменил функцию, добавив второе условие, но криво. Это ерунда. Я его уже убрал.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 1)
Ответ на: комментарий от Ceiling_QB

А, ну да, логично. Спасибо, понял. Оно же в любом случае вернет нил, если что не так. Не подумал. Хм. И я не знал, что можно возвращать не переменные. Я думал оно только их возвращает.

А вот про то что цикл сам увеличивает, я уже понял. Это просто по привычке уже. Я сначала тестировал - увеличивает или нет. Вроде увеличивало, но я для надежности прибавлял.

LightDiver ★★★★★
() автор топика
Последнее исправление: LightDiver (всего исправлений: 2)