ShadoW DaemoN
offline
Опыт:
37,078Активность: |
Распространенные ошибки Jass программистов (by ADOLF)
Автор: ADOLF.
Распространенные ошибки Jass программистовМне недалече довелось побывать оценщиком работ на конкурс способностей. Изумленно наблюдал я незнание, казалось бы, банальных вещей, досадность упущений иногда просто вводила в ступор меня. По порядку говорить начну я, сложным закончу, с простого начну. Приводить примеры буду я только из карт реальных, на конкурс присланных.
Оформление кода.Вот отрывок кода, его надо несколько раз перечитать, чтобы понять, к какому блоку что относиться. Мне сначала показалось, что endloop - окончание функции, далее идет объявление другой. Логику расстановки отступов понять я так и не смог.
((код jass
local real StartLife = 0.
local real EndLife = 0. if Time < 1 and GetWidgetLife(Dummy) > 0.405 then call GroupEnumUnitsInRange(Group,X,Y,120,null) loop set Picked = FirstOfGroup(Group) exitwhen Secret_Pirouette_Filter(Caster,Picked) == true or Picked == null call GroupRemoveUnit(Group,Picked) endloop if Picked != null then
if LoadBoolean(udg_Hashtable,Handle,7) == true then set StartLife = GetUnitState(Picked,UNIT_STATE_LIFE) endif call UnitDamageTarget(Caster,Picked,Damage, true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null) call Secret_Pirouette_DPS(Caster,Picked,25,LoadBoolean(udg_Hashtable,Handle,7)) call DummyCastTarget(Caster,Picked,Level,'A001',"thunderbolt")//Raw-code if LoadBoolean(udg_Hashtable,Handle,7) == true then set EndLife = GetUnitState(Picked,UNIT_STATE_LIFE) call TextTag(Picked,udg_PlayerColors[GetPlayerId(GetOwningPlayer(Caster))+1]+"-"+I2S(R2I(StartLife-EndLife))+"|r",8) endif call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\WingedSerpentMissile\\WingedSerpentMissile.mdl",Picked,"origin")) call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl",Picked,"origin")) call KillUnit(Dummy) call SaveReal(udg_Hashtable,Handle,9,10) endif ===== call SetUnitX(Dummy,X+Speed*Cos(Angle-25)) call SetUnitY(Dummy,Y+Speed*Sin(Angle-25)) )) Добавить побольше ASCII-графики, можно написать, какое у вас настроение, или скопировать старый анекдот, что бы код было читать веселее.
((код jass
*********************\\-------------------------------------------------------\\
=====================\\ *** * ***** **** **** ***** * * \\ Timer Library \\ * * * * * * * * * * * * * \\ by \\ ***** * **** ** **** **** **** *** \\ ALEXPREY © \\ * * * * * * * * * * * * \\ =====================\\ * ***** ***** * * ***** ** \\ *********************\\-------------------------------------------------------\\ )) Даешь осмысленные комментарии! ФИЛЬТР! Я СКАЗАЛ
((код jass
ФИЛЬТР!
=============================== function Secret_Pirouette_Filter takes unit Caster,unit Picked returns boolean return IsUnitEnemy(Picked,GetOwningPlayer(Caster)) and GetWidgetLife(Picked) > 0.405 and not IsUnitType(Picked,UNIT_TYPE_STRUCTURE) and not IsUnitType(Picked,UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(Picked,UNIT_TYPE_MECHANICAL) endfunction =============================== )) На десерт.
((код jass
function Chat_Space takes nothing returns nothing
_________________________________________________ call ClearTextMessages() _________________________________________________ endfunction )) Хорош тот код, который не нуждается в комментариях. Назовите функцию CreateTextTag*** (OnUnit например) - и будет вам счастье.
((код jass
Проверка на неуязвимость. Автор - DioD (from XGM forum)
... Вывод текста. Автора нет. function TextTag takes unit u, string text, real height returns texttag
)) Перебор юитов в группах."Милый, заберешь сегодня нашего малого из детского садика."
Милый идет в садик, забирает оттуда домой всех детей, приводит их домой и начинает по одному проверять, не его ли это сын, если нет - отправляет ребенка назад в садик. Также обратите внимание на b == true. Это неправильно. Для надежности надо писать (b == true and b != false), этому нас еще в свое время MPI3 учил. На самом деле надо писать просто b, например if b then... ((код jass
local group Group = CreateGroup()
... call GroupEnumUnitsInRange(Group,X,Y,120,null) loop set Picked = FirstOfGroup(Group) exitwhen Secret_Pirouette_Filter(Caster,Picked) == true or Picked == null call GroupRemoveUnit(Group,Picked) endloop ... call DestroyGroup(Group) set Group = null )) Правильно:
((код jass
c_temp и t_temp - глобальные переменные
gr_temp - Глобальная, всегда пустая группа, создання для переборов юнитов JASS
function foo takes nothing returns boolean if t_temp == null and SecretPirouetteFilter (c_temp, GetFilterUnit()) then set t_temp = GetFilterUnit() endif return false endfunction ... set c_temp = Caster set t_temp = null call GroupEnumUnitsInRange (gr_temp, x, y, 120., Condition(function Foo)) cJass
c_temp = Caster t_temp = null GroupEnumUnitsInRange (gr_temp, x, y, 120., Condition(lambda boolean () { if (t_temp == null && SecretPirouetteFilter (c_temp, GetFilterUnit()) { t_temp = GetFilterUnit() } return false })) ))
При работе с глобальными переменными, используемыми многими функциями, важно учитывать возможность остановки потока и запуска другого, в котором она может быть перезаписана. Запись в хешЧто это за ключ 1? Юнит-пустышка? Юнит, применивший способность? Цель? А вы наверное и переменные называете u1, u2 и т.д.?
((код jass
call SaveUnitHandle(udg_Hash,GetHandleId(t),1,u)
)) Неправильно решение проблемы - высока возможность опечатки, да и вообще, криво это все.
((код jass
call RemoveSavedHandle(udg_Hashtable,GetHandleId(Caster),StringHash("Omnislash Caster Trigger"))
)) Внимание, правильный ответ:
((код jass
JASS
globals constant integer HASHKEY_OMNISLASH_CASTER = 1 constant integer HASHKEY_OMNISLASH_TARGET = 2 endglobals ... call RemoveSavedHandle (udg_Hashtable, GetHandleId(Caster), HASHKEY_OMNISLASH_CASTER) cJass
enum (HASHTABLENAME_KEYS) { HASHKEY_OMNISLASH_CASTER HASHKEY_OMNISLASH_TARGET } ... RemoveSavedHandle (udg_Hashtable, GetHandleId(Caster), HASHKEY_OMNISLASH_CASTER) ))
Обнулить всё!Чем больше всего обнулить, тем быстрее будет работать.
((код jass
local real StartLife = 0.
local real EndLife = 0. ... set StartLife = 0. set EndLife = 0. )) Самые продвинутые обнуляют даже boolean.
((код jass
local boolean TextMessages = true
... set TextMessages = false endfunction )) Скалярные локальные переменные обнулять не нужно. Не нужно! Ещё раз - не нужно! integer, boolean, real не нужно обнулять. Вообще, сам термин обнуления некорректен. Утечки могут быть вызваны удаленными объектами, на которые остались ссылки. Читайте мое добавление к статье Сергея "Осваиваем jass", там об этом подробно. Отредактировано ShadoW DaemoN, 28.04.2011 в 17:07. |
27.04.2011, 21:23 | #1
+11/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Doc
offline
Опыт:
63,163Активность: |
Даеш еще!
Алсо не очень понял что там про комментарии к функции TextTag.
Установил статус важной :3 |
27.04.2011, 21:47 | #2
+4/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Nekit1234007
offline
Опыт:
11,916Активность: |
Шик. Неужели кто-то подумал, что перебор группы лупом хорошо оценят? |
27.04.2011, 21:55 | #3
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
iZucken
ШТО
offline
Опыт:
17,960Активность: |
Вкусно :3 какое счастье, за мной ничего этого не водится |
27.04.2011, 22:07 | #4
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hanabishi
COOL STATUS
offline
Опыт: отключен
|
круто, адик умеет "ненавязчиво ткнуть рожей" в ошибки=) |
27.04.2011, 22:41 | #5
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Rampage
Бицепс
offline
Опыт:
9,722Активность: |
Да, я краб. Ну что ж.
Rampage добавил:
Я ни одной статьи не прочитал про Jass, и обнулял реальные. Кстати, это спелл я из-за крабовства и отменил. В Omnislash'e максимально аккуратно делал.
Чем плохо? Нормально. |
28.04.2011, 13:04 | #6
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
DotaMaster666
Silenced by GadenbIsh
offline
Опыт:
1,259Активность: |
|
28.04.2011, 13:15 | #7
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
spellwerk
offline
Опыт:
4,869Активность: |
действительно ужасно =( Spy_ добавил:
и, кстати, может я чего то не понимаю:
не проще ли
? |
28.04.2011, 14:03 | #8
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hanabishi
COOL STATUS
offline
Опыт: отключен
|
Spy_, ну там могут быть кастом цифры, не связанные напрямую с уровнем |
28.04.2011, 14:25 | #9
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
SRes
1110101000
offline
Опыт:
9,997Активность: |
"некоректен"
Некорректен. После безграмотных дотеров большую часть ошибок не заметил, каюсь. Дополнил: "например: if b then..." Как-то по китайски написан первый абзац. Так мастер Йода писал бы, уверен я. Отредактировано SRes, 28.04.2011 в 16:23. |
28.04.2011, 15:51 | #10
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Rewenger
The culprit will not die
offline
Опыт:
35,273Активность: |
поддержим грамматического нациста выше
вот уж действительно
|
28.04.2011, 16:06 | #11
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Clamp
Lost in space
offline
Опыт:
71,258Активность: |
ShadoW_DaemoN:
плакал =) ShadoW_DaemoN: уже даже не плакал - рыдал! =DDDD |
28.04.2011, 16:20 | #12
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Master_chan
Полуночный командир
offline
Опыт:
15,660Активность: |
Написано под впечатлением от проверки Spell Contest. пораньше бы Т_Т |
28.04.2011, 16:56 | #13
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ARHUI
offline
Опыт:
3,341Активность: |
Код:
Я конечно понимаю, что это не весь код, но разве такая реализация применима к случаю запуска кода несколько раз подряд, переменные не успеют перезаписаться? Я ни в коем случае не критикую, сам ещё разбираюсь... |
29.04.2011, 21:24 | #14
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
agentex
offline
Опыт:
34,534Активность: |
не успеют |
29.04.2011, 21:29 | #15
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
DioD
offline
Опыт:
45,184Активность: |
ошибка номер 0 - Они считают себя программистами. |
30.04.2011, 15:17 | #16
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hanabishi
COOL STATUS
offline
Опыт: отключен
|
кстати да, это всё равно что web-дизайнеры себя программистами посчитают, т.к. по факту jass - это скрипт |
30.04.2011, 18:00 | #17
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Faion
Noblesse Oblige
offline
Опыт:
30,395Активность: |
Ну раз заговорили о читабельности...
Обратил внимание что все юзеры cjass оформляют код вот так: Код:
Рекомендую для большей читабельности оформлять вот так: Код:
В сложных конструкциях подобное оформление существенно облегчает работу с различными конструкциями. или Код:
Просто пример компактного оформления=) Так же отмечу что такое оформление удобно тем, что при сворачивании кода(я о +\- слева конструкций) оставляет "верхушку", так становится понятнее что свернули. Думаю те кто юзают C# меня поддержут=) Так же рекомендую всем создавать под себя как можно больше функций даже под простые вещи, такие как: Код:
К примеру: Код:
или Код:
|
30.04.2011, 23:09 | #18
+1/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Doc
offline
Опыт:
63,163Активность: |
Faion, зачем функции лол? дефайны на что? алсо, насчет скобочек, я везде так пишу, screenshot.su/show.php?img=939863ae17352e866cf356cdef844637.jpg , т.к. имхо это правильнее, хотя это личное дело каждого. |
30.04.2011, 23:17 | #19
+2/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Faion
Noblesse Oblige
offline
Опыт:
30,395Активность: |
Цитата:
Рандомный пример для тех то були обнуляет, очевидно же. Цитата:
ну вс автоматом подобным образом проставляет блоки и хочу отметить что значительно делает код читабельнее. |
||
30.04.2011, 23:20 | #20
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|