Skip to content

Instantly share code, notes, and snippets.

@killofwin
Created January 6, 2014 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save killofwin/8283475 to your computer and use it in GitHub Desktop.
Save killofwin/8283475 to your computer and use it in GitHub Desktop.
Public Function SymmetryMorfidTrue(UnitMorfid As UnitClass) As Integer
' Функция возвращает True если Морфид собран в 2D редакторе симетрично.
' Возвращает значение отличное от True если какая то часть не валидна, в битовой маске этого числа
' обозначены неисправные конечности.
' Поэтому проверку на неправильность конечностей надо делать if r <> True , а не if r = false
' О как!
' Она обращает внимание лишь на godc классы редактора ID которого записан в констате Editor2dPartUnitMorfid
' Для реального игрового контроля будет использоваться другой механизм, в котором клиентом на сервер будет передаваться
' список файлов из которых в дальнейшем и будет сформирован юнит. А так же список генетических программ которые
' будут задействованы в юните
' Генетическая программа это тригер и действие. Тригером может служить фермент или достижение нужной массы определённой частью.
' А действие как выработка другого фермента, так и команда на рост, апоптоз или морфирование определённой части в другую.
' По сути это будут простейшие линейные скриптыиспользующие в качестве условий ферментные флаги.
' Так же некоторые юниты смогут распылять произвольные ферменты при помощи желез запуская те или иные последовательности
' в других юнитах
Dim a As Integer
Dim b As Integer
Dim bc As Integer ' дополнительный счётчик
Dim p As Integer
Dim m As Integer
Dim PartsGODC As GameObjectDataClass[] ' ссылки на нужные godc свойства частей юнита
Dim tp As Integer ' указатель в UnitMorfid.Parts[a].OtherValues
Dim r As Integer ' результат
Dim Parity As Boolean ' чётность конечности
Dim SymD As New Boolean[] ' проверить дублиование тех конечностей которые отмечены как True (дублирование)
Dim SymB As New Boolean[] ' проверить отсутствие тех конечностей которые помечены как True (блокирование)ъ
Dim SymStrings As New String[] ' Ожидаемая строка проверки симметрии
Dim UMC As Integer
p = UnitMorfid.Parts.Max ' максимальный индекс
UMC = UnitMorfid.Parts.Count ' Общее колличество элементов включая 0
SymD.Resize(UMC)
SymB.Resize(UMC)
SymStrings.Resize(UMC)
' Изменение размеров массивов до размерности массива конечностей
r = True
If UMC < 1 Then
' У юнита есть части
PartsGODC.Resize(UMC)
For a = 0 To p
' Присвоение ссылок заранее для облегчения кодирования
tp = UnitMorfid.Parts[a].OtherValues.FindID(Editor2dPartUnitMorfid) ' ссылка на данные редактора морфидов
If tp <> -1 Then
'Данные по конечности найдены
PartsGODC[a] = UnitMorfid.Parts[a].OtherValues.Values[tp] ' Собственно сама ссылка
Endif
If tp = -1 Then
' часть создавалась явно не как Editor2dPartUnitMorfid
PartsGODC[a] = NewBlankGameObjectData(Editor2dPartUnitMorfid) ' присвоить пустышку 'изначально тут использовался вызов функции с параметрами "по умолчанию" но это делало код менее очевидным, исправил.
Endif
Next
For a = 0 To p 'перебор частей
If r = False Then Break ' досрочный выход если результат уже отрицательный
'Если проверка провалилась на раннем этапе, если она не провалилась, значит надо проверить каждую часть на валидность
If a > p Then Break ' На всякий случай, а то мало ли что :)
If a > 1 Then
Parity = Not Parity ' инвертирование чётности . Значение True значит что конечность чётная
Endif
If (SymB[a] Or SymD[a]) = False Then ' Конечность не является не блокированной и не дублированной
' Теперь надо проверить на своём ли она месте
If PartsGODC[a].IntegerValues[PropertyPartUnitTypeSymmetry] <> 2 Then
' Конечность должна быть чётной
If Parity = False And a > 0 Then r = False ' Но конечность НЕчётная и не нулевая.
Endif
If PartsGODC[a].IntegerValues[PropertyPartUnitTypeSymmetry] <> 1 Then
' Конечность должна быть НЕчётной
If Parity = True And a > 0 Then r = False ' Но конечность чётная и не нулевая.
Endif
If r <> False Then 'конечность прошла предыдущую проверку, (она на своём месте)
'Теперь последует проверка на маски, не выхядят ли они за границы колличества конечностей
' А теперь надо наиболее изящным образом организовать проверку
' Думаю сначала следует вычислить не являеться ли число больше чем оставшееся к перебору колличество конечностей
' Полагаю стоит вычислить позиции максимального бита.
If (a + MaxBit(PartsGODC[a].IntegerValues[PropertyPartUnitMorfidMaskD])) - 1 > MorfidMaxLimb Then
'Если колличечество конечностей больше лимита конечностей
If r = True Then r = False ' что бы не манипулировать битами отрицательного числа
r = BSet(r, a - 1) ' присовение нужного бита, функция BSet(Number, bit) считает биты начиная с 0 нулевого.
Endif
bc = 0 ' Установка битов блокирования
For b = a + 1 To p
bc = bc + 1 ' бит из маски который следует считать
'А теперь считываем нужный бит из битовой маски
If SymB[b] <> True Then
SymB[b] = BTst(PartsGODC[a].IntegerValues[PropertyPartUnitMorfidMaskB], bc) ' Необходимо пояснение, чуть сам не запутался:
Endif
' Есть условие, оно необходимо что бы симметрия не оказалась отменена, она может только быть присвонной TRUE
' от нуля до p все конечности принимает аргументы c нуля
' симметрия рассматриваеться включительно, то есть нулевой бит в маске указывает на саму же конечность, поэтому он и игнорируеться
' сделанно так для упрощения попыток вообразить себе всё это
Next
bc = 0 ' Установка битов дублирования
For b = a + 1 To p
bc = bc + 1 ' бит из маски который следует считать
'А теперь считываем нужный бит из битовой маски
If SymD[b] <> True Then
SymD[b] = BTst(PartsGODC[a].IntegerValues[PropertyPartUnitMorfidMaskD], bc) ' присваиваем бит
SymStrings[b] = PartsGODC[a].Strings[PropertyPartUnitMorfidSymmetryString] ' присвоение строки по которой проверяется симметрия
Endif
Next
Endif 'конечность прошла предыдущую проверку, (она на своём месте)
Endif ' Конечность не является не блокированной и не дублированной
If SymD[a] = True Then
' Дублированная конечность
' Надо проверить равно ли свойство конечности строке симметрии
If PartsGODC[a].Strings[PropertyPartUnitMorfidSymmetryString] <> SymStrings[a] Then
' Таки не равно, значит надо внечти в результат соответствующую маску
' Если что, нулевая конечность вне симметрии, но -1 надо всё равно сделать, потому что BSet считает первый бит нулевым
r = BSet(r, a - 1) ' собственно присвоение
Endif
Endif
If SymB[a] = True Then
' Блокированная конечность
' Надо проверить равно ли свойство конечности ""
If PartsGODC[a].Strings[PropertyPartUnitMorfidSymmetryString] <> "" Then
' Таки не равно, значит надо внечти в результат соответствующую маску
' Если что, нулевая конечность вне симметрии, но -1 надо всё равно сделать, потому что, потому что BSet считает первый бит нулевым
r = BSet(r, a - 1) ' собственно присвоение
Endif
Endif
Next 'перебор частей
Endif
Return r
End
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment