Программы
Предназначение:
Работа с кодом
Warcraft III Reforged привнес в игру скрипты Lua, но многие разработчики карт для WC3 до сих пор используют JASS, а многие и cJass (просто потому, что правила синтаксиса в стиле C тупо рулят) К сожалению, расширение cJass не поддерживается для Reforged, и кто знает, как это будет, вероятнее всего вряд ли c-подобный синтаксис появится в Reforged. А JASS устаревает, крайне дырявый и имеет громоздкий и неудобный синтаксис.
Lua более эффективен, полезен и прост в разработке игр, он фактически стал стандартом в игровом скриптинге благодаря своему удобству, простоте и быстроте. Но многие проекты все еще находятся на cJass/JASS, и нет возможности конвертировать их в Lua. Редактор без расширения cJass не воспринимает этот код и в результате ваш проект может просто пропасть. А многие у кого проект написан на JASS предпочли бы переписать его на более удобный Lua, который легче и приятнее поддерживать. Переписывание кода вручную для Lua может занять много времени, само собой никто не хочет тратить на это время, чтоб делать свой проект фактически второй раз.
Этот инструмент создан, чтобы решить эту проблему. cJass2Lua может легко конвертировать cJass и JASS в читаемый Lua код, он поможет вам менее болезненно перенести код своей карты с JASS и cJass который находится в тупиковом положении на код в Lua. В большинстве случаев при переносе кода его даже не нужно редактировать, чтобы заставить работать, допустимо даже подавать мешанину из cJass и JASS кода на вход.
Скриншот:
Возможности:
  • Полная поддержка cJass и JASS
  • Возможность комбинировать синтаксис этих двух языков в одном файле
  • Поддержка парсинга структур(классов) в Lua'шные объекты мета-таблиц совместимые с оригинальным кодом, зачастую не требующие даже внесения правок чтобы они работали
  • Примитивный синтаксический анализ (на правильность кода) в процессе парсинга и вывод ошибок в лог
  • Генерация Lua кода на основе вашего cJass/JASS кода
  • Генерация спец-комментариев emmyDoc для Lua, которые помогают IDE ориентироваться в коде
  • Способен конвертировать common.j, blizzard.j и JASS код любой сложности
  • Удобный выбор файла/папки с файлами
  • Конвертация одиночных файлов
  • Массовая конвертация файлов из папки в папку
  • Подробное логгирование всех действий программы в лог файл для анализа проблем
  • Распознавание пост-инкрементов и пре-инкрементов
  • 100% читабельный код на выходе
  • Сохраняет комментарии, их позиции и переносы строк в любых местах
  • Сохраняет совместимость кода и его изначальную планировку (порой достаточно просто конвертировать текст каждого триггера по отдельности и ваша карта уже работает на Lua)
  • Расставляет табуляцию
  • Конфигурационный файл с настройками
  • Минималистичный встроенный графический интерфейс где удобно и подробно можно отслеживать прогресс
  • Интерфейс командной строки
Ограничения:
  • Отсутствует и вряд ли планируется семантический анализатор. За семантику выражений отвечает автор скриптов.
  • Структуры не поддерживают наследование и не понимают разницу между public и private (поддерживаются статические методы, статические переменные переводятся в глобальные)
  • Отсутствие поддержки расширенных фич vJASS как module, library, scope (Они по сути в Lua и не нужны, и просто игнорируются при парсе)
  • Не поддерживаются пре-процессорные директивы (Лишено смысла при переводе в Lua)
  • Макросы ограничены. блоки define распознаются, но только как константы. Избегайте функциональных макросов.
  • В некоторых случаях массивы в Lua индексируются с единицы, в большинстве случаев вам это ничем не грозит, но имейте в виду.
  • Инкременты в выражениях выгдядят так a = (var++) --> a = (var + 1). Но сам var в этом случае не увеличится на 1, нужно фиксить руками.
  • Циклы for из cJass не поддерживаются и вряд ли будут, перед тем как транслировать файл на Lua - сохраните его на диск.
  • Всё на английском языке
Внимание:
Перед преобразованием кода, убедитесь что...
  • Ваш код на 100% правильный и не содержит ошибок
  • Ваши структуры не используют наследование
  • Если в вашей структуре предусмотрен конструктор (статический "создавальщик") то он обязан называться new или create
  • Если у вас в коде используются структуры не объявленные в этом файле, объявите их в начале файла при помощи type StructName, так парсер поймет с чем имеет дело
  • Не используются ключевые слова в качестве идентификаторов. Такие как do, else, while, then и тд.
  • Имейте в виду, что хоть и присутствует умная замена оператора конкатенации строк, строчные идентификаторы и функции объявленные в других файлах не будут распознаны как строки и если + не поменялся на .. - это придется делать вручную.
Приложение оставляет после своей работы рядом с собой лог файл, читайте его если вдруг что-то не так. Когда нормально отрабатывает приложение - там не должно быть ни одного сообщения типа Warning, Critical или Fatal.
Пример преобразования:
//Входящий JASS/cJass код
type Projectile

bool KatonItachiConditions()
{
	if (GetSpellAbilityId() == 'A07Z')
	{
		return true;
	}

	return false;
}

define
	KATON_DUMMY           =  1
	KATON_RADIUS		  =  2
	KATON_DAMAGE		  =  3
	KATON_FINAL_POINT_X   =  4
	KATON_FINAL_POINT_Y   =  5
	KATON_EFFECT          =  6
	KATON_DIRECTION       =  7
	KATON_TRAVELED        =  8
	KATON_DMG_FACTOR      =  9
	
	
	KATON_DISTANCE        =  1100
	KATON_VELOCITY        =  5.35
enddefine

globals 
	unit g_KatonDummy;
	float g_KatonDMG;
	trigger g_TrgKatonPreCast;
endglobals

void KatonItachiActions()
{
	unit u = GetTriggerUnit();
	player p = GetOwningPlayer(u);
	location loc = GetSpellTargetLoc();
	location myLoc = GetUnitLoc(u);
	float facing = GetUnitFacing(u);
	location spawnPoint = PolarProjectionBJ(myLoc, 115.00, facing);
	location finalPoint = PolarProjectionBJ(spawnPoint, KATON_DISTANCE, facing);
	int lvl = GetUnitAbilityLevel(u, GetSpellAbilityId());
	float r = 200 + (25 * (lvl - 1));
	float dmg = 10;//10 + (4 * (lvl - 1)); 
	float travelFactor = 0.006 + (0.002 * (lvl - 1));
	float dummyScale = 2.00 + (0.30 * (lvl - 1));
	
	timer t = CreateTimer();
	InitPeriodicTimer(t, 0.01, 3.5);
	unit dummy =  CreateDummy(p, u, spawnPoint);
	SetUnitPathing(dummy, false);
	effect e = AddSpecialEffectTarget("fireball.mdx", dummy, "origin");
	SetUnitScale(dummy, dummyScale, dummyScale, dummyScale);
	SaveUnitHandle(g_Hashtable, GetHandleId(t), KATON_DUMMY, dummy);
	SaveReal(g_Hashtable, GetHandleId(t), KATON_RADIUS, r);
	SaveReal(g_Hashtable, GetHandleId(t), KATON_DAMAGE, dmg);
	SaveReal(g_Hashtable, GetHandleId(t), KATON_DMG_FACTOR, travelFactor);
	SaveReal(g_Hashtable, GetHandleId(t), KATON_DIRECTION, facing);
	SaveReal(g_Hashtable, GetHandleId(t), KATON_TRAVELED, 0);
	SaveReal(g_Hashtable, GetHandleId(t), KATON_FINAL_POINT_X, GetLocationX(finalPoint));
	SaveReal(g_Hashtable, GetHandleId(t), KATON_FINAL_POINT_Y, GetLocationY(finalPoint));
	SaveEffectHandle(g_Hashtable, GetHandleId(t), KATON_EFFECT, e);
	
	RemoveLocation(spawnPoint);
	RemoveLocation(loc);
	RemoveLocation(myLoc);
	RemoveLocation(finalPoint);
	
	TimerStart(t, 0.01, true, lambda void ()
	{
		timer t = GetExpiredTimer();
		float dur = GetTimerDuration(t);
		unit dummy = LoadUnitHandle(g_Hashtable, GetHandleId(t), KATON_DUMMY);
		location dummyLoc = GetUnitLoc(dummy);
		float r = LoadReal(g_Hashtable, GetHandleId(t), KATON_RADIUS);
		float traveled = LoadReal(g_Hashtable, GetHandleId(t), KATON_TRAVELED);
		float dir = LoadReal(g_Hashtable, GetHandleId(t), KATON_DIRECTION);
		float finalPointX = LoadReal(g_Hashtable, GetHandleId(t), KATON_FINAL_POINT_X);
		float finalPointY = LoadReal(g_Hashtable, GetHandleId(t), KATON_FINAL_POINT_Y);
		location newLoc = PolarProjectionBJ(dummyLoc, KATON_VELOCITY, dir);
		SetUnitPositionLoc(dummy, newLoc);
		RemoveLocation(newLoc);
		RemoveLocation(dummyLoc);
		traveled += KATON_VELOCITY;
		SaveReal(g_Hashtable, GetHandleId(t), KATON_TRAVELED, traveled);
		
		if (ModuloInteger(R2I(dur * 100), 10) == 0)
		{
			group g = CreateGroup();
			float travelFactor = LoadReal(g_Hashtable, GetHandleId(t), KATON_DMG_FACTOR);
			float dmg = LoadReal(g_Hashtable, GetHandleId(t), KATON_DAMAGE) + (traveled * travelFactor);
			g_KatonDummy = dummy;
			g_KatonDMG = dmg;
			boolexpr bexp = Condition(lambda bool ()
			{
				unit u = GetFilterUnit();
				if (!IsPlayerAlly(GetOwningPlayer(u), GetOwningPlayer(g_KatonDummy)) && !IsUnitType(u, UNIT_TYPE_STRUCTURE) && IsUnitAlive(u) && !IsUnitDummy(u))
				{
					return true;
				}
				return false;
			});
			GroupEnumUnitsInRange(g, GetUnitX(dummy), GetUnitY(dummy), r, bexp);
			ForGroup(g, lambda void ()
			{
				 DummyDealDamage(g_KatonDummy, GetEnumUnit(), g_KatonDMG, SCHOOL_MAGIC);
			});
			SaveReal(g_Hashtable, GetHandleId(t), KATON_DAMAGE, dmg);
			DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl", GetUnitX(dummy), GetUnitY(dummy)));
			DestroyBoolExpr(bexp);
			DestroyGroup(g);
		}
		
		
		
		if (!TimerTick(t) || dummy == null || traveled > KATON_DISTANCE)
		{
			DestroyEffect(LoadEffectHandle(g_Hashtable, GetHandleId(t), KATON_EFFECT));
			RemoveUnit_s(dummy, "KatonItachiActions", "KatonItachi");
			DestroyTimer_s(t);
		}
	});
}

void KatonSoundActions()
{
	unit u = GetTriggerUnit();
	AddSoundUnit("katon.mp3", u);
	u = null;
}

void KatonItachiActionsNew()
{
	unit u = GetTriggerUnit();
	location loc = GetSpellTargetLoc();
	int lvl = GetUnitAbilityLevel(u, GetSpellAbilityId());
	float r = 200 + (25 * (lvl - 1));
	float dmg = 100;//100 + (4 * (lvl - 1)); 
	float travelFactor = 0.04 + (0.02 * (lvl - 1));
	float dummyScale = 2.00 + (0.30 * (lvl - 1));
	
	FinishDuel();
	Projectile katonProj = Projectile.create(DEFAULT_DUMMY, "fireball.mdx", dummyScale, u, 110);
	katonProj.SetVelocity(535, 1.0);
	katonProj.DamageOnce(false);
	katonProj.SetDamageData(0.1, dmg, r, 0, 0, travelFactor, SCHOOL_MAGIC);
	katonProj.SetDestLoc(loc);
	katonProj.SetDistance(1100, true);
	katonProj.InstantRemove(true);
	katonProj.SetDamageEffect("Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl");
	katonProj.Launch();
	
	RemoveLocation(loc);
	u = null;
	loc = null;
}

void InitTrig_KatonItachi()
{
    gg_trg_KatonItachi = CreateTrigger();
	g_TrgKatonPreCast = CreateTrigger();
    TriggerRegisterAnyUnitEventBJ(gg_trg_KatonItachi, EVENT_PLAYER_UNIT_SPELL_EFFECT);
	TriggerRegisterAnyUnitEventBJ(g_TrgKatonPreCast, EVENT_PLAYER_UNIT_SPELL_CHANNEL);
    TriggerAddCondition(gg_trg_KatonItachi, Condition(function KatonItachiConditions));
    TriggerAddAction(gg_trg_KatonItachi, function KatonItachiActionsNew);
	TriggerAddCondition(g_TrgKatonPreCast, Condition(function KatonItachiConditions));
    TriggerAddAction(g_TrgKatonPreCast, function KatonSoundActions);
}
-- Lua код на выходе

---@class  Projectile
---@return bool
function KatonItachiConditions()
	if (GetSpellAbilityId() == FourCC('A07Z')) then
		return true
	end
	
	return false
end

KATON_DUMMY = 1	---@type integer	
KATON_RADIUS = 2	---@type integer	
KATON_DAMAGE = 3	---@type integer	
KATON_FINAL_POINT_X = 4	---@type integer	
KATON_FINAL_POINT_Y = 5	---@type integer	
KATON_EFFECT = 6	---@type integer	
KATON_DIRECTION = 7	---@type integer	
KATON_TRAVELED = 8	---@type integer	
KATON_DMG_FACTOR = 9	---@type integer	
KATON_DISTANCE = 1100	---@type integer	
KATON_VELOCITY = 5.35	---@type real	

-- g_KatonDummy	---@type unit	
-- g_KatonDMG	---@type float	
-- g_TrgKatonPreCast	---@type trigger	

---@return void
function KatonItachiActions()
	local u = GetTriggerUnit()
	local p = GetOwningPlayer(u)
	local loc = GetSpellTargetLoc()
	local myLoc = GetUnitLoc(u)
	local facing = GetUnitFacing(u)
	local spawnPoint = PolarProjectionBJ(myLoc, 115.00, facing)
	local finalPoint = PolarProjectionBJ(spawnPoint, KATON_DISTANCE, facing)
	local lvl = GetUnitAbilityLevel(u, GetSpellAbilityId())
	local r = 200 + (25 * (lvl - 1))
	local dmg = 10	-- 10 + (4 * (lvl - 1)); 
	local travelFactor = 0.006 + (0.002 * (lvl - 1))
	local dummyScale = 2.00 + (0.30 * (lvl - 1))
	
	local t = CreateTimer()
	InitPeriodicTimer(t, 0.01, 3.5)
	local dummy = CreateDummy(p, u, spawnPoint)
	SetUnitPathing(dummy, false)
	local e = AddSpecialEffectTarget("fireball.mdx", dummy, "origin")
	SetUnitScale(dummy, dummyScale, dummyScale, dummyScale)
	SaveUnitHandle(g_Hashtable, GetHandleId(t), KATON_DUMMY, dummy)
	SaveReal(g_Hashtable, GetHandleId(t), KATON_RADIUS, r)
	SaveReal(g_Hashtable, GetHandleId(t), KATON_DAMAGE, dmg)
	SaveReal(g_Hashtable, GetHandleId(t), KATON_DMG_FACTOR, travelFactor)
	SaveReal(g_Hashtable, GetHandleId(t), KATON_DIRECTION, facing)
	SaveReal(g_Hashtable, GetHandleId(t), KATON_TRAVELED, 0)
	SaveReal(g_Hashtable, GetHandleId(t), KATON_FINAL_POINT_X, GetLocationX(finalPoint))
	SaveReal(g_Hashtable, GetHandleId(t), KATON_FINAL_POINT_Y, GetLocationY(finalPoint))
	SaveEffectHandle(g_Hashtable, GetHandleId(t), KATON_EFFECT, e)
	
	RemoveLocation(spawnPoint)
	RemoveLocation(loc)
	RemoveLocation(myLoc)
	RemoveLocation(finalPoint)
	
	TimerStart(t, 0.01, true, function ()
		local t = GetExpiredTimer()
		local dur = GetTimerDuration(t)
		local dummy = LoadUnitHandle(g_Hashtable, GetHandleId(t), KATON_DUMMY)
		local dummyLoc = GetUnitLoc(dummy)
		local r = LoadReal(g_Hashtable, GetHandleId(t), KATON_RADIUS)
		local traveled = LoadReal(g_Hashtable, GetHandleId(t), KATON_TRAVELED)
		local dir = LoadReal(g_Hashtable, GetHandleId(t), KATON_DIRECTION)
		local finalPointX = LoadReal(g_Hashtable, GetHandleId(t), KATON_FINAL_POINT_X)
		local finalPointY = LoadReal(g_Hashtable, GetHandleId(t), KATON_FINAL_POINT_Y)
		local newLoc = PolarProjectionBJ(dummyLoc, KATON_VELOCITY, dir)
		SetUnitPositionLoc(dummy, newLoc)
		RemoveLocation(newLoc)
		RemoveLocation(dummyLoc)
		traveled = traveled + KATON_VELOCITY
		SaveReal(g_Hashtable, GetHandleId(t), KATON_TRAVELED, traveled)
		
		if (ModuloInteger(R2I(dur * 100), 10) == 0) then
			local g = CreateGroup()
			local travelFactor = LoadReal(g_Hashtable, GetHandleId(t), KATON_DMG_FACTOR)
			local dmg = LoadReal(g_Hashtable, GetHandleId(t), KATON_DAMAGE) + (traveled * travelFactor)
			g_KatonDummy = dummy
			g_KatonDMG = dmg
			local bexp = Condition(function ()
				local u = GetFilterUnit()
				if ( not IsPlayerAlly(GetOwningPlayer(u), GetOwningPlayer(g_KatonDummy)) and  not IsUnitType(u, UNIT_TYPE_STRUCTURE) and IsUnitAlive(u) and  not IsUnitDummy(u)) then
					return true
				end
				return false
			end)
			GroupEnumUnitsInRange(g, GetUnitX(dummy), GetUnitY(dummy), r, bexp)
			ForGroup(g, function ()
				DummyDealDamage(g_KatonDummy, GetEnumUnit(), g_KatonDMG, SCHOOL_MAGIC)
			end)
			SaveReal(g_Hashtable, GetHandleId(t), KATON_DAMAGE, dmg)
			DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl", GetUnitX(dummy), GetUnitY(dummy)))
			DestroyBoolExpr(bexp)
			DestroyGroup(g)
		end
		
		
		if ( not TimerTick(t) or dummy == nil or traveled > KATON_DISTANCE) then
			DestroyEffect(LoadEffectHandle(g_Hashtable, GetHandleId(t), KATON_EFFECT))
			RemoveUnit_s(dummy, "KatonItachiActions", "KatonItachi")
			DestroyTimer_s(t)
		end
	end)
end

---@return void
function KatonSoundActions()
	local u = GetTriggerUnit()
	AddSoundUnit("katon.mp3", u)
	u = nil
end

---@return void
function KatonItachiActionsNew()
	local u = GetTriggerUnit()
	local loc = GetSpellTargetLoc()
	local lvl = GetUnitAbilityLevel(u, GetSpellAbilityId())
	local r = 200 + (25 * (lvl - 1))
	local dmg = 100	-- 100 + (4 * (lvl - 1)); 
	local travelFactor = 0.04 + (0.02 * (lvl - 1))
	local dummyScale = 2.00 + (0.30 * (lvl - 1))
	
	FinishDuel()
	local katonProj = Projectile:create(DEFAULT_DUMMY, "fireball.mdx", dummyScale, u, 110)
	katonProj.SetVelocity(535, 1.0)
	katonProj.DamageOnce(false)
	katonProj.SetDamageData(0.1, dmg, r, 0, 0, travelFactor, SCHOOL_MAGIC)
	katonProj.SetDestLoc(loc)
	katonProj.SetDistance(1100, true)
	katonProj.InstantRemove(true)
	katonProj.SetDamageEffect("Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl")
	katonProj.Launch()
	
	RemoveLocation(loc)
	u = nil
	loc = nil
end

---@return void
function InitTrig_KatonItachi()
	gg_trg_KatonItachi = CreateTrigger()
	g_TrgKatonPreCast = CreateTrigger()
	TriggerRegisterAnyUnitEventBJ(gg_trg_KatonItachi, EVENT_PLAYER_UNIT_SPELL_EFFECT)
	TriggerRegisterAnyUnitEventBJ(g_TrgKatonPreCast, EVENT_PLAYER_UNIT_SPELL_CHANNEL)
	TriggerAddCondition(gg_trg_KatonItachi, Condition(KatonItachiConditions))
	TriggerAddAction(gg_trg_KatonItachi, KatonItachiActionsNew)
	TriggerAddCondition(g_TrgKatonPreCast, Condition(KatonItachiConditions))
	TriggerAddAction(g_TrgKatonPreCast, KatonSoundActions)
end

Инструкция:
Чтобы пользоваться просто укажите во входящий путь в окне приложения путь к файлу или папке с cjass/jass файлами при помощи кнопки Browse. Чтобы выбрать папку, а не файл - нажмите Browse с зажатым шифтом. Внизу укажите путь к папке в которую запишется готовый Lua файл (или прямой путь к выходному луа файлу), выбор файла или папки через Browse аналогичен. Также имеется и консольный интерфейс (первый аргумент входящий путь, второй - исходящий). Если исходящий путь не указан, то .lua файлик сохранится туда же, где и входящий .j файлик.
СКАЧАТЬ: (версия v1.12 07.12.2019)
x86 сборка: Скачать
x64 сборка: Скачать
Исходный код (и подробности использования):
GitHub: github.com/fullmetal-a/cjass2lua
Изменения v1.12:
  • Исправлены все случаи, когда this. не добавлялся периодически перед членами и методами
  • Исправлен баг, когда иногда оператор ! заменялся на - вместо not
  • Теперь все названия методов корректны и полностью работоспособны, они больше не пишутся через :
  • Добавлена поддержка .deallocate
  • Теперь переменная объекта текущего класса, созданная в методе .create при помощи .allocate удаляется при трансляции кода, а все обращения к ней меняются на this.
  • Исправлено множество багов
Изменения v1.11/1.10:
  • Улучшен парсинг
  • Улучшен консольный интерфейс
  • Исправлены редкие критические баги
  • Исправлен критический баг с трансляцией идентификаторов
  • Теперь поля входящих и выходящих путей в интерфейсе больше не read-only
Изменения v1.09:
  • Добавлена поддержка перевода структур/классов в мета-табличные объекты
  • Добавлена поддержка коротких void лямбда-выражений через оператор ()->
  • Парс теперь прерывается с ошибкой если мы переобъявляем глобальную функцию\переменную
  • Небольшие улучшения и оптимизация
  • Исправления багов
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
3
16
5 лет назад
3
Выкатил обновление с учетом большинства замечаний выше, обновил описание, как одобрят можете проверять (или с гитхаба качайте)
2
30
5 лет назад
2
Сурсы неожиданно приятные, кстати.
0
1
5 лет назад
0
Clamp:
Тебе прямо на экране загрузки пишет «эта карта не использует cJass»
в треде самой карты обычно пишут на чём она сделана, особенно если это не стандартный jass или gui. Да и пара-тройка системных переменных в .j файлах не сказать что прячутся.
PT153:
особые текстовые смайлы
особыми эмодзи можно было бы посчитать с десяток лет назад. Кто же знал?
0
16
5 лет назад
0
в треде самой карты обычно пишут на чём она сделана,
Да да, конечно, везде пишут "да и кстати я ее на cJass писал. Это средство разработки , всем пофигу на чем работает карта. И вообще, все нормальные карты проходят через оптимайзер и обфусцируются до обычной каши из jass. И не все карты выкладывают в места вроде хгм, например я свой проект который уже несколько лет делаю. Так что давай без поспешных выводов.
2
29
5 лет назад
2
Довольно бесполезно без поддержки структур и т.д. + реализация слишком базовая, нет никакой гарантии что код в итоге выйдет корректным (та же конкатенация строк).
Подбросить в срач, делал несколько карт на сжасс, в тредах этого не упоминал.
2
16
5 лет назад
Отредактирован Drulia_san
2
Doc:
Довольно бесполезно без поддержки структур и т.д
Это так, те кто кто обильно пользуются структурами не смогут получить выгоды от этой утилиты, а те у кого 1-2 класса (но много экземпляров создается повсеместно) могут их переписать вручную и просто поменять объявления объектов\их использование. Но в будущем я всё же добавлю поддержку структур с их последующей конвертацией в мета-табличные реализации. Да я не думаю что абсолютно все ими прямо таки активно пользуются в картах, мне разве что класс снарядов понадобился, который их метает с кучей различных вариаций, а так по большей части чисто функциональщина. (Я не утверждаю как персонаж выше что структуры не востребованы, у всех по-разному).
Doc:
реализация слишком базовая, нет никакой гарантии что код в итоге выйдет корректным (та же конкатенация строк).
Для скриптов с чисто функциональным подходом почти идеально так как поддерживаются все базовые фичи языка (плюс некоторые дополнительные), к примеру в одной своей карте пару десятков триггеров конвертировал (там одна функциональщина на cJass) и получилось довольно неплохо, разве что в некоторых триггерах пришлось конкатенацию строк руками подправить и всё работает. Ну код все равно придется проверять, но намного меньше грязной работы, ради чего собственно и весь движ.
0
29
5 лет назад
0
В целом советую подумать о разборе типов переменных, система типов в жассе/вжасс очень банальная энивей и ничего принципиально сложного быть не должно.
2
16
5 лет назад
2
Doc:
В целом советую подумать о разборе типов переменных, система типов в жассе/вжасс очень банальная энивей и ничего принципиально сложного быть не должно.
Хорошо, учту это
0
1
5 лет назад
0
Drulia_san:
конечно, везде пишут
всем пофигу на чем работает карта
Doc:
делал несколько карт на сжасс, в тредах этого не упоминал
не везде, а обычно. Однако, если не пишут, то я сам спрашиваю, если заинтересовался картой.
Drulia_san:
не все карты выкладывают в места вроде хгм
да, вот тут мои аргументы хворают, в эту эфемерную карту я ясное дело поиграл ментально, но так как физического доступа у меня к ней нету, то я так и не узнал про неё ничего.
2
16
5 лет назад
Отредактирован Drulia_san
2
ProstoParya:
Drulia_san:
в эту эфемерную карту я ясное дело поиграл ментально
то я сам спрашиваю
Никому нет дела до твоего отношения к cJass и до того, что ты считаешь его невостребованным, к тому, что ты конечно же в курсе про все карты на свете и на чем они там сделаны, успокойся.
Заинтересованным: И да, как было предложено выше - я реализовал распознавание строк и строчных переменных\аргументов\функций. При склеивании их оператор + должен корректно меняться на ..
Осталось добавить парсинг структур и всё.
2
16
5 лет назад
2
Апдейт
Добавил поддержку обычного JASS, теперь можно конвертировать любые скрипты вообще. Но пока что структуры всё еще не поддерживаются.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.