18

» WarCraft 3 / Отключили свет = минус карта

TeX13, карта в весе не потеряла после такой процедуры?
если в весе не потеряла и бекапов нигде нету - то скинь карту сюда или в лс, я попробую пошаманить
на крайний случай всегда можно вытащить war3map.wpm (ландшафт)
18

» WarCraft 3 / Отключили свет = минус карта

если не поможет - то последняя запущенная с редактора карта должна лежать по пути:
C:\Users\%USERNAME%\AppData\Local\Temp\Maps\Test
(просто вбей это в строку над проводником)
Так у 1.31, хз как в 1.30
P.S. "запущенная" через кнопку "Проверка карты"
18

» WarCraft 3 / Где и как считать свойства карты?

vasya1, парсится и чисто русское имя
у тебя просто нету карты с таким именем
вот сайт с кодами ошибок
Загруженные файлы
18

» WarCraft 3 / Где и как считать свойства карты?

vasya1, проблема знака '-' в том что не получится в пути написать пробелы, поэтому лучше путь пихать в кавычки "")
только нафиг '-' писать) Да и вообще никто так не делает вроде)

вроде решил проблему
Загруженные файлы
18

» WarCraft 3 / Где и как считать свойства карты?

vasya1, не может быть) У меня всё открывалось и там нету разницы по формату) Откроется даже TurtleRock.txt
А сама карта больше нигде не открыта? Никакие приложения не используют её?

Забыл в инструкцию добавить:
можно просто запустить карту с помощью pw3i.exe (тупо навести на .exe), output в этом случае должен сохраниться там где лежала карта
А из cmd примерно вот так: pw3i.exe "D:\Warcraft 3\Maps\TurtleRock.w3x"

И ещё надо учесть что строки могут содержать переходы, походу надо кидать строки в блок {}

vasya1, ух ладно короче ща по феншую допилю отображение полного названия ошибки
заодно засуну строки в {}
Загруженные файлы
18

» WarCraft 3 / Где и как считать свойства карты?

vasya1, number of players это кол-во игроков заданное редактором
к примеру ты сделал в игре 5 игроков, остальные 7 выключены и num of players будет стоять на пяти.
Да, я накосячил, указывать игроков и так и так не нужно.
Мне во время парса игроков надо запомнить какие в игре, а какие нет (долго объяснять почему, просто лишние 12 игроков прилипали к первому клану при 24 игроках)

8gabriel8:
Такую штуку хочешь запилить?
я подумаю)

vasya1,

и ещё кое что хотел сказать:
.w3i может ссылаться на строки из war3map.wts
у меня есть парсер который составляет таблицу строк из .wts
но одно большое но
раскрыть
.wts должен быть строго по шаблону:
STRING 123
{
text
}
просто иногда есть люди которые ради незначительной экономии размера или красоты сокращают .wts до такого шаблона:
STRING 123
{text}
и ещё есть туча способов и варкрафт их прочитает
WorldEditor собирает .wts по первому шаблону
а точить парсер .wts под все случаи и ошибки в .wts - такое себе
поэтому я в output.txt добавил отображение номера TRIGSTR (если он конечно используется, т.к в .w3i можно писать строки не ссылась в .wts)
Загруженные файлы
18

» WarCraft 3 / Где и как считать свойства карты?

Steal nerves, да ладно фиг с этой статьей, в ней есть неточности
в основном это перепутаны флаги
пруф
в .w3i лежит инфа о кланах, в том числе их флаги
чтобы проще понять - эти флаги идут как набор единиц и нулей (да/нет), читаются справа налево и у кланов их пять
От "Союзник" до "Общие войска: все"
Так вот
Я собрал карту, взял флаг и там написано 11000, т.е если исходить из той статьи
раскрыть
0x00000001: allied (force 1)
0x00000002: allied victory
0x00000004: share vision
0x00000010: share unit control
0x00000020: share advanced unit control
у меня должны стоять галки на "Общие войска" и "Общие войска: все"
но проблема вот в чем:
я конечно сразу посчитал это тем что я не выспался, поэтому вручную каждый флаг перепроверял и всё равно не совпадает со статьей
Вот правильный список составил:
0x00000001 Allied
0x00000002 Share victory
0x00000004 Share advanced unit control
0x00000008 Share vision
0x00000010 Share unit control

В общем собрал парсер, инструкция в архиве
Точность не гарантирую, но вроде все пункты правильно парсятся)
P.S. Технологии/Способности/Улучшения/Случайные предметы/Таблицы предметов не стал делать, т.к это геморройно и долго очень
Загруженные файлы
18

» WarCraft 3 / Где и как считать свойства карты?

vasya1,
нуууу, это не совсем скрипт, это считай кусок кода из хостбота
Экспорт в .txt можно сделать, но не раньше чем завтра (мб к вечеру освобожусь)
18

» WarCraft 3 / Где и как считать свойства карты?

это с гитхаба украл:
HANDLE SubFile;

if( SFileOpenFileEx( MapMPQ, "war3map.w3i", 0, &SubFile ) )
{
	uint32_t FileLength = SFileGetFileSize( SubFile, NULL );

	if( FileLength > 0 && FileLength != 0xFFFFFFFF )
	{
		char *SubFileData = new char[FileLength];
		DWORD BytesRead = 0;

		if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead, NULL ) )
		{
			istringstream ISS( string( SubFileData, BytesRead ) );

			// war3map.w3i format found at http://www.wc3campaigns.net/tools/specs/index.html by Zepir/PitzerMike

			string GarbageString;
			uint32_t FileFormat;
			uint32_t RawMapWidth;
			uint32_t RawMapHeight;
			uint32_t RawMapFlags;
			uint32_t RawMapNumPlayers;
			uint32_t RawMapNumTeams;

			ISS.read( (char *)&FileFormat, 4 );				// file format (18 = ROC, 25 = TFT)

			if( FileFormat == 18 || FileFormat == 25 )
			{
				ISS.seekg( 4, ios :: cur );					// number of saves
				ISS.read( (char *)&EditorVersion, 4 );		// editor version
				getline( ISS, GarbageString, '\0' );		// map name
				getline( ISS, GarbageString, '\0' );		// map author
				getline( ISS, GarbageString, '\0' );		// map description
				getline( ISS, GarbageString, '\0' );		// players recommended
				ISS.seekg( 32, ios :: cur );				// camera bounds
				ISS.seekg( 16, ios :: cur );				// camera bounds complements
				ISS.read( (char *)&RawMapWidth, 4 );		// map width
				ISS.read( (char *)&RawMapHeight, 4 );		// map height
				ISS.read( (char *)&RawMapFlags, 4 );		// flags
				ISS.seekg( 1, ios :: cur );					// map main ground type

				if( FileFormat == 18 )
					ISS.seekg( 4, ios :: cur );				// campaign background number
				else if( FileFormat == 25 )
				{
					ISS.seekg( 4, ios :: cur );				// loading screen background number
					getline( ISS, GarbageString, '\0' );	// path of custom loading screen model
				}

				getline( ISS, GarbageString, '\0' );		// map loading screen text
				getline( ISS, GarbageString, '\0' );		// map loading screen title
				getline( ISS, GarbageString, '\0' );		// map loading screen subtitle

				if( FileFormat == 18 )
					ISS.seekg( 4, ios :: cur );				// map loading screen number
				else if( FileFormat == 25 )
				{
					ISS.seekg( 4, ios :: cur );				// used game data set
					getline( ISS, GarbageString, '\0' );	// prologue screen path
				}

				getline( ISS, GarbageString, '\0' );		// prologue screen text
				getline( ISS, GarbageString, '\0' );		// prologue screen title
				getline( ISS, GarbageString, '\0' );		// prologue screen subtitle

				if( FileFormat == 25 )
				{
					ISS.seekg( 4, ios :: cur );				// uses terrain fog
					ISS.seekg( 4, ios :: cur );				// fog start z height
					ISS.seekg( 4, ios :: cur );				// fog end z height
					ISS.seekg( 4, ios :: cur );				// fog density
					ISS.seekg( 1, ios :: cur );				// fog red value
					ISS.seekg( 1, ios :: cur );				// fog green value
					ISS.seekg( 1, ios :: cur );				// fog blue value
					ISS.seekg( 1, ios :: cur );				// fog alpha value
					ISS.seekg( 4, ios :: cur );				// global weather id
					getline( ISS, GarbageString, '\0' );	// custom sound environment
					ISS.seekg( 1, ios :: cur );				// tileset id of the used custom light environment
					ISS.seekg( 1, ios :: cur );				// custom water tinting red value
					ISS.seekg( 1, ios :: cur );				// custom water tinting green value
					ISS.seekg( 1, ios :: cur );				// custom water tinting blue value
					ISS.seekg( 1, ios :: cur );				// custom water tinting alpha value
				}

				ISS.read( (char *)&RawMapNumPlayers, 4 );	// number of players
				uint32_t ClosedSlots = 0;

				for( uint32_t i = 0; i < RawMapNumPlayers; ++i )
				{
					CGameSlot Slot( 0, 255, SLOTSTATUS_OPEN, 0, 0, 1, SLOTRACE_RANDOM );
					uint32_t Colour;
					uint32_t Status;
					uint32_t Race;

					ISS.read( (char *)&Colour, 4 );			// colour
					Slot.SetColour( Colour );
					ISS.read( (char *)&Status, 4 );			// status

					if( Status == 1 )
						Slot.SetSlotStatus( SLOTSTATUS_OPEN );
					else if( Status == 2 )
					{
						Slot.SetSlotStatus( SLOTSTATUS_OCCUPIED );
						Slot.SetComputer( 1 );
						Slot.SetComputerType( SLOTCOMP_NORMAL );
					}
					else
					{
						Slot.SetSlotStatus( SLOTSTATUS_CLOSED );
						++ClosedSlots;
					}

					ISS.read( (char *)&Race, 4 );			// race

					if( Race == 1 )
						Slot.SetRace( SLOTRACE_HUMAN );
					else if( Race == 2 )
						Slot.SetRace( SLOTRACE_ORC );
					else if( Race == 3 )
						Slot.SetRace( SLOTRACE_UNDEAD );
					else if( Race == 4 )
						Slot.SetRace( SLOTRACE_NIGHTELF );
					else
						Slot.SetRace( SLOTRACE_RANDOM );

					ISS.seekg( 4, ios :: cur );				// fixed start position
					getline( ISS, GarbageString, '\0' );	// player name
					ISS.seekg( 4, ios :: cur );				// start position x
					ISS.seekg( 4, ios :: cur );				// start position y
					ISS.seekg( 4, ios :: cur );				// ally low priorities
					ISS.seekg( 4, ios :: cur );				// ally high priorities

					if( Slot.GetSlotStatus( ) != SLOTSTATUS_CLOSED )
						Slots.push_back( Slot );
				}

				ISS.read( (char *)&RawMapNumTeams, 4 );		// number of teams

				for( uint32_t i = 0; i < RawMapNumTeams; ++i )
				{
					uint32_t Flags;
					uint32_t PlayerMask;

					ISS.read( (char *)&Flags, 4 );			// flags
					ISS.read( (char *)&PlayerMask, 4 );		// player mask

					for( unsigned char j = 0; j < MAX_SLOTS; ++j )
					{
						if( PlayerMask & 1 )
						{
							for( vector<CGameSlot> :: iterator k = Slots.begin( ); k != Slots.end( ); ++k )
							{
								if( (*k).GetColour( ) == j )
									(*k).SetTeam( i );
							}
						}

						PlayerMask >>= 1;
					}

					getline( ISS, GarbageString, '\0' );	// team name
				}

				// the bot only cares about the following options: melee, fixed player settings, custom forces
				// let's not confuse the user by displaying erroneous map options so zero them out now

				MapOptions = RawMapFlags & ( MAPOPT_MELEE | MAPOPT_FIXEDPLAYERSETTINGS | MAPOPT_CUSTOMFORCES );
				CONSOLE_Print( "[MAP] calculated map_options = " + UTIL_ToString( MapOptions ) );
				MapWidth = UTIL_CreateByteArray( (uint16_t)RawMapWidth, false );
				CONSOLE_Print( "[MAP] calculated map_width = " + UTIL_ByteArrayToDecString( MapWidth ) );
				MapHeight = UTIL_CreateByteArray( (uint16_t)RawMapHeight, false );
				CONSOLE_Print( "[MAP] calculated map_height = " + UTIL_ByteArrayToDecString( MapHeight ) );
				MapNumPlayers = RawMapNumPlayers - ClosedSlots;
				CONSOLE_Print( "[MAP] calculated map_numplayers = " + UTIL_ToString( MapNumPlayers ) );
				MapNumTeams = RawMapNumTeams;
				CONSOLE_Print( "[MAP] calculated map_numteams = " + UTIL_ToString( MapNumTeams ) );

				uint32_t SlotNum = 1;

				for( vector<CGameSlot> :: iterator i = Slots.begin( ); i != Slots.end( ); ++i )
				{
					CONSOLE_Print( "[MAP] calculated map_slot" + UTIL_ToString( SlotNum ) + " = " + UTIL_ByteArrayToDecString( (*i).GetByteArray( ) ) );
					++SlotNum;
				}

				if( MapOptions & MAPOPT_MELEE )
				{
					CONSOLE_Print( "[MAP] found melee map, initializing slots" );

					// give each slot a different team and set the race to random

					unsigned char Team = 0;

					for( vector<CGameSlot> :: iterator i = Slots.begin( ); i != Slots.end( ); ++i )
					{
						(*i).SetTeam( Team++ );
						(*i).SetRace( SLOTRACE_RANDOM );
					}

					MapFilterType = MAPFILTER_TYPE_MELEE;
				}

				if( !( MapOptions & MAPOPT_FIXEDPLAYERSETTINGS ) )
				{
					// make races selectable

					for( vector<CGameSlot> :: iterator i = Slots.begin( ); i != Slots.end( ); ++i )
						(*i).SetRace( (*i).GetRace( ) | SLOTRACE_SELECTABLE );
				}
			}
		}
		else
			CONSOLE_Print( "[MAP] unable to calculate map_options, map_width, map_height, map_slot<x>, map_numplayers, map_numteams - unable to extract war3map.w3i from MPQ file" );

		delete [] SubFileData;
	}

	SFileCloseFile( SubFile );
}
и ещё есть тоже самое, но я переделывал под 1.31 (надо поискать у себя)
18

» WarCraft 3 / Где и как считать свойства карты?

В war3map.w3i всё хранится
В ROC картах он чуть отличается от TFT
Если говорить по версиям, то близзарды .w3i меняли только в 1.31 чтобы добавить пункт с луа и еще какие то 4 константы + они убрали различие между ROC и TFT картами (т.е и в тех и в других будет одна и та же структура .w3i)

У меня есть сурс от парсера, но он заточен чтобы брать нужные значения, типа высота-ширина карты и т.д
И там нету гуи)
Ну всмысле тупо код чтобы распарсить .w3i
18

» WarCraft 3 / cJass -> vJass

PT153:
Чего ж сразу ручками, можно же из карты собранный jass вытащить)
Вот этот вариант самый верный.
Тут есть один нюанс
Привычные переносы строки это сочетание 0x0D0A
Вакрафту пофиг на такие переносы, он пережует и 0D и 0A хоть по отдельности, а вот блокнот поломается)
если у cJass включена оптимизация - то пишется 0A, тулы векса пишут 0D
я специально написал parsed_war3map.j, а не optimized_war3map.j (чтобы люди, не имеющие под рукой hex редактор смогли читать код)
оптимизация включена - в vJass парсер передается optimized_war3map.j, выключена - то передается parsed_war3map.j

И в каком месте вариант самый верный если вопрос был о vJass?
Парсер cJass'а парсит код прямо в vJass, т.к он обязан парсить в том числе конструкции vJass которые написаны на cJass, то что оптимизирует - согласен
scope TestScope
{
}
//Разве может на выходе это оказаться сразу в JASS2?)
//Это пропарсится в
scope TestScope
endscope
//А уже потом JassHelper (vJass) из этого соберет war3map.j

Мой вариант практичнее всего, т.к выигрывает время на зарезервированных словах типа "function" и т.д

А насчет
некоторых хитрых конструкций
Блин, можно в пустой карте комментариями оградить нужный код в одном "триггере", а дальше имхо быстрее будет выделять и делать таб, чем сидеть и писать тучу букв
а дальше
ну я имел в виду после того как карта пропарсится
18

» WarCraft 3 / cJass -> vJass

в jngp сначала код обрабатывает парсер cJass'a, потом vJass'a
если подумать логически, то cJass и так на выходе должен выдать код на vJass

берешь вырубаешь vJass, сохраняешь карту и берешь уже готовый код по пути ...\Jass New Gen Pack Rebuild\AdicHelper\parsed_war3map.j
upd:
пардон, vJass можно не отключать)
18

» WarCraft 3 / Лаги при создание юнитов через loop

set U_D = CreateUnit(GetOwningPlayer(U), 'uban', X, Y, (bj_forLoopAIndex-1)*10.00 )
Загруженные файлы
18

» WarCraft 3 / Rikimaru из DotA 6.83d

NazarPunk, а где я говорил что я лучше кого то?
я сказал что понимаю в ассемблере, но опыта очень не хватает и тяжело искать нужный/годный мануал
надоели, честное слово
что ни скажи - то понт
18

» WarCraft 3 / Rikimaru из DotA 6.83d

quq_CCCP, а не, походу не только строки из ""
в .rdata так же лежит

NazarPunk:
Дык я вообще электрослесарь подземный 4го разряда и это ничего не значит.
знал бы ты как тяжело искать нужные мануалы, а ведь ещё самому их понимать приходится
а на лекции всё по полочкам и по буквам рассказывают
Загруженные файлы
18

» WarCraft 3 / Rikimaru из DotA 6.83d

quq_CCCP:
Мб они патчат оригинальный скрипт так, чтобы исправить баги.
не, там не именно строки из скрипта
в .rdata прячутся именно все строки которые под "" бывают в.j

блин, реально ощущение такое что они вышли за рамки вм jass'a и код доты исполняется прямо "над варкрафтом"

это резонней, "нативный мемхак", меньше лагов и т.д
18

» WarCraft 3 / Rikimaru из DotA 6.83d


quq_CCCP, вот нашел один сегмент и там подозрительные константы (.rdata это сегмент констант как я помню)
вот байтовый массив 'Ogre Magi has a lot of survivability but he does need the ability'
и таких ещё дофига
'ReplaceableTextures\CommandButtons\BTNHeroTinker.blp'

попробую по их адресу порыть че нибудь

нашел перекрестные ссылки в сегменте .text
аж даже интересно стало
.text сегмент это вроде уже сам исполняемый код, блин, у меня такое ощущение что они этим .exe собирают что то
т.к эти константы почему то ровно в столбик передаются куда то
18

» WarCraft 3 / Rikimaru из DotA 6.83d

Bergi_Bear, для бара-варс можно такую идею сделать:
скорость разгона будет разной, если оба бары столкнутся - то победит тот, у кого скорость разгона выше ну или итемы такие то
ещё может быть вот так, один бара стоит - другой разогнался, второй прилетел и убил первого бару, т.к тот стоял (т.е скорость разгона 0)
игра будет что то типа вышибал