Довольно сложно будет кинуть прям весь код или внятно полностью объяснить что там происходит, потому что кода правда оочень много, там много объектов вложенных в другие объекты и тд. Заранее извиняюсь за трудные объяснения. У меня проблема, к примеру у меня есть класс снапшота состояний зданий на карте. Он хранит в себе состояния всех зданий на карте в определенный момент времени. В свою очередь каждое состояние отдельного здания это тоже объект, который имеет члены "здоровье", "тип юнита", "уязвим\неуязвим", "позиция", "игрок". Также в объект снапшота всех зданий отдельно записываются типы юнитов крипов, которые регулярно спавнятся.
Снапшоты состояний в свою очередь пишутся в контейнер типа очереди (не обращайте внимание что я назвал это стек) предназначенный специально для этих снапшотов.
И в общем проблема следующая: Я заметил что хоть все данные из снапшота можно применить (восстановить здания как были в момент n), но почему-то типы сохраненных крипов всегда равны 0. Покопавшись в дебаге, в метод применения самого снапшота к карте я вывел this и он показывает что равен нулю. Как это может быть и почему?
Если что методы типа TSH_WriteBool и тд - просто пишут в хеш-таблицу, это просто костыли которые я тестировал во время дебага, не обращаем внимания.
Код класса состояния здания:
class StructureSnapshot
{
	private unit origin;
	private int typeId;
	private float face;
	private float life;
	private float posX;
	private float posY;
	private player owner;

	static method create takes unit u returns StructureSnapshot
		StructureSnapshot obj = StructureSnapshot.allocate();
		obj.typeId = GetUnitTypeId(u);
		obj.face = GetUnitFacing(u);
		if (IsUnitDead(u))
		{
			obj.life = 0;
		}
		else
		{
			obj.life = GetUnitLife(u);
		}
		if (obj.life > 0)
		{
			TSH_WriteBool(obj, TS_STRUCT_INVUL, IsStructureInvul(u));
		}
		else
		{
			TSH_WriteBool(obj, TS_STRUCT_INVUL, false);
		}
		obj.posX = GetUnitX(u);
		obj.posY = GetUnitY(u);
		obj.owner = GetOwningPlayer(u);
		obj.origin = u;
		return obj;
	endmethod
	
	method destroy takes void returns void
		origin = null;
		owner = null;
		TSH_Flush(this);
		this.deallocate();
	endmethod
	
	method IsAlive takes void returns bool
		bool b = (life > 0);
		return b;
	endmethod
	
	method Restore takes void returns unit
		if (!this.IsAlive())
		{
			return origin;
		}
		
		bool invul = TSH_ReadBool(this, TS_STRUCT_INVUL);
		if (IsUnitAlive(origin))
		{
			SetUnitLife(origin, life);
			SetUnitInvulnerable(origin, invul);
			return origin;
		}
		
		unit u = CreateUnit(owner, typeId, posX, posY, face);
		SetUnitLife(u, life);
		if (invul)
		{
			SetUnitInvulnerable(u, true);
		}
		return u;
	endmethod
};
Код снапшота состояния всех зданий на карте:\
StructureSnapshot StrucTakeSnapshot(unit u)
{
	return StructureSnapshot.create(u);
}

class StructuresSnapshot
{
	private StructureSnapshot a_Top[3];
	private StructureSnapshot a_Mid[3];
	private StructureSnapshot a_Bot[3];

	private StructureSnapshot h_Top[3];
	private StructureSnapshot h_Mid[3];
	private StructureSnapshot h_Bot[3];

	private StructureSnapshot a_Prot[2];
	private StructureSnapshot h_Prot[2];

	private StructureSnapshot a_bar_Top[2];
	private StructureSnapshot a_bar_Mid[2];
	private StructureSnapshot a_bar_Bot[2];

	private StructureSnapshot h_bar_Top[2];
	private StructureSnapshot h_bar_Mid[2];
	private StructureSnapshot h_bar_Bot[2];
	
	private bool hNoBar;
	private bool aNoBar;

	static method create takes void returns StructuresSnapshot
		StructuresSnapshot obj = StructuresSnapshot.allocate();
		///////////////////////////////////////////////
		obj.a_Top[0] = StrucTakeSnapshot(g_ATT1);
		obj.a_Top[1] = StrucTakeSnapshot(g_ATT2);
		obj.a_Top[2] = StrucTakeSnapshot(g_ATT3);
		
		obj.a_Mid[0] = StrucTakeSnapshot(g_AMT1);
		obj.a_Mid[1] = StrucTakeSnapshot(g_AMT2);
		obj.a_Mid[2] = StrucTakeSnapshot(g_AMT3);
		
		obj.a_Bot[0] = StrucTakeSnapshot(g_ABT1);
		obj.a_Bot[1] = StrucTakeSnapshot(g_ABT2);
		obj.a_Bot[2] = StrucTakeSnapshot(g_ABT3);
		///////////////////////////////////////////////
		obj.h_Top[0] = StrucTakeSnapshot(g_HTT1);
		obj.h_Top[1] = StrucTakeSnapshot(g_HTT2);
		obj.h_Top[2] = StrucTakeSnapshot(g_HTT3);
		
		obj.h_Mid[0] = StrucTakeSnapshot(g_HMT1);
		obj.h_Mid[1] = StrucTakeSnapshot(g_HMT2);
		obj.h_Mid[2] = StrucTakeSnapshot(g_HMT3);
		
		obj.h_Bot[0] = StrucTakeSnapshot(g_HBT1);
		obj.h_Bot[1] = StrucTakeSnapshot(g_HBT2);
		obj.h_Bot[2] = StrucTakeSnapshot(g_HBT3);
		///////////////////////////////////////////////
		obj.a_Prot[0] = StrucTakeSnapshot(g_AT41);
		obj.a_Prot[1] = StrucTakeSnapshot(g_AT42);
		
		obj.h_Prot[0] = StrucTakeSnapshot(g_HT41);
		obj.h_Prot[1] = StrucTakeSnapshot(g_HT42);
		///////////////////////////////////////////////
		obj.a_bar_Top[0] = StrucTakeSnapshot(g_ATopBar1);
		obj.a_bar_Top[1] = StrucTakeSnapshot(g_ATopBar2);
		
		obj.a_bar_Mid[0] = StrucTakeSnapshot(g_AMidBar1);
		obj.a_bar_Mid[1] = StrucTakeSnapshot(g_AMidBar2);
		
		obj.a_bar_Bot[0] = StrucTakeSnapshot(g_ABotBar1);
		obj.a_bar_Bot[1] = StrucTakeSnapshot(g_ABotBar2);
		///////////////////////////////////////////////
		obj.h_bar_Top[0] = StrucTakeSnapshot(g_HTopBar1);
		obj.h_bar_Top[1] = StrucTakeSnapshot(g_HTopBar2);
		
		obj.h_bar_Mid[0] = StrucTakeSnapshot(g_HMidBar1);
		obj.h_bar_Mid[1] = StrucTakeSnapshot(g_HMidBar2);
		
		obj.h_bar_Bot[0] = StrucTakeSnapshot(g_HBotBar1);
		obj.h_bar_Bot[1] = StrucTakeSnapshot(g_HBotBar2);
		//////////////////////////////////////////////
		
		obj.hNoBar = g_HNoBarracks;
		obj.aNoBar = g_ANoBarracks;
		
		TSH_Write(obj, DEF_a_ct_top_Meele, g_AMC_Top);
		TSH_Write(obj, DEF_a_ct_top_Ranged, g_ARC_Top);
		TSH_Write(obj, DEF_a_ct_mid_Meele, g_AMC_Mid);
		TSH_Write(obj, DEF_a_ct_mid_Ranged, g_ARC_Mid);
		TSH_Write(obj, DEF_a_ct_bot_Meele, g_AMC_Bot);
		TSH_Write(obj, DEF_a_ct_bot_Ranged, g_ARC_Bot);
		
		TSH_Write(obj, DEF_h_ct_top_Meele, g_HMC_Top);
		TSH_Write(obj, DEF_h_ct_top_Ranged, g_HRC_Top);
		TSH_Write(obj, DEF_h_ct_mid_Meele, g_HMC_Mid);
		TSH_Write(obj, DEF_h_ct_mid_Ranged, g_HRC_Mid);
		TSH_Write(obj, DEF_h_ct_bot_Meele, g_HMC_Bot);
		TSH_Write(obj, DEF_h_ct_bot_Ranged, g_HRC_Bot);
		
		return obj;
	endmethod
	
	method destroy takes void returns void
		int i = 0;
		while (i < 2)
		{
			a_Prot[i].destroy();
			h_Prot[i].destroy();
			a_bar_Top[i].destroy();
			a_bar_Bot[i].destroy();
			a_bar_Mid[i].destroy();
			h_bar_Top[i].destroy();
			h_bar_Bot[i].destroy();
			h_bar_Mid[i].destroy();
			i++;
		}
		
		i = 0;
		while (i < 3)
		{
			a_Top[i].destroy();
			a_Mid[i].destroy();
			a_Bot[i].destroy();
			h_Top[i].destroy();
			h_Mid[i].destroy();
			h_Bot[i].destroy();
			i++;
		}
		TSH_Flush(this);
		this.deallocate();
	endmethod
	
	method Restore takes void returns void
		g_ATT1 = a_Top[0].Restore();
		g_ATT2 = a_Top[1].Restore();
		g_ATT3 = a_Top[2].Restore();

		g_AMT1 = a_Mid[0].Restore();
		g_AMT2 = a_Mid[1].Restore();
		g_AMT3 = a_Mid[2].Restore();

		g_ABT1 = a_Bot[0].Restore();
		g_ABT2 = a_Bot[1].Restore();
		g_ABT3 = a_Bot[2].Restore();
		///////////////////////////////////////////////
		g_HTT1 = h_Top[0].Restore();
		g_HTT2 = h_Top[1].Restore();
		g_HTT3 = h_Top[2].Restore();

		g_HMT1 = h_Mid[0].Restore();
		g_HMT2 = h_Mid[1].Restore();
		g_HMT3 = h_Mid[2].Restore();

		g_HBT1 = h_Bot[0].Restore();
		g_HBT2 = h_Bot[1].Restore();
		g_HBT3 = h_Bot[2].Restore();
		///////////////////////////////////////////////
		g_AT41 = a_Prot[0].Restore();
		g_AT42 = a_Prot[1].Restore();

		g_HT41 = h_Prot[0].Restore();
		g_HT42 = h_Prot[1].Restore();
		///////////////////////////////////////////////
		g_ATopBar1 = a_bar_Top[0].Restore();
		g_ATopBar2 = a_bar_Top[1].Restore();

		g_AMidBar1 = a_bar_Mid[0].Restore();
		g_AMidBar2 = a_bar_Mid[1].Restore();

		g_ABotBar1 = a_bar_Bot[0].Restore();
		g_ABotBar2 = a_bar_Bot[1].Restore();
		///////////////////////////////////////////////
		g_HTopBar1 = h_bar_Top[0].Restore();
		g_HTopBar2 = h_bar_Top[1].Restore();

		g_HMidBar1 = h_bar_Mid[0].Restore();
		g_HMidBar2 = h_bar_Mid[1].Restore();

		g_HBotBar1 = h_bar_Bot[0].Restore();
		g_HBotBar2 = h_bar_Bot[1].Restore();
		///////////////////////////////////////////////
		
		g_HNoBarracks = hNoBar;
		g_ANoBarracks = aNoBar;
		
				//Если здесь вывести this то он будет равен нулю
		
		g_AMC_Top = TSH_Read(this, DEF_a_ct_top_Meele); 
		g_ARC_Top = TSH_Read(this, DEF_a_ct_top_Ranged);
		g_AMC_Mid = TSH_Read(this, DEF_a_ct_mid_Meele);
		g_ARC_Mid = TSH_Read(this, DEF_a_ct_mid_Ranged);
		g_AMC_Bot = TSH_Read(this, DEF_a_ct_bot_Meele);
		g_ARC_Bot = TSH_Read(this, DEF_a_ct_bot_Ranged);
		
		g_HMC_Top = TSH_Read(this, DEF_h_ct_top_Meele);
		g_HRC_Top = TSH_Read(this, DEF_h_ct_top_Ranged);
		g_HMC_Mid = TSH_Read(this, DEF_h_ct_mid_Meele);
		g_HRC_Mid = TSH_Read(this, DEF_h_ct_mid_Ranged);
		g_HMC_Bot = TSH_Read(this, DEF_h_ct_bot_Meele);
		g_HRC_Bot = TSH_Read(this, DEF_h_ct_bot_Ranged);
	endmethod
};

StructuresSnapshot TakeMapStructuresSnapshot()
{
	return StructuresSnapshot.create();
}
И код контейнера снапшотов:
class StrucStack
{
	private StructuresSnapshot m_arr[256];
	private int m_size;
	private int m_maxSize;

	
	static method create takes int maxSize returns StrucStack
		StrucStack obj = StrucStack.allocate();
		obj.m_size = 0;
		
		if (maxSize > 1024)
		{
			obj.m_maxSize = 1024;
			GMSG("|cFFFFFF00Warning: |r maxSize of StrucStack exceeds 256! It is set to 256.");
		}
		else
		{
			obj.m_maxSize = maxSize;
		}
		
		int i = 0;
		while (i < obj.m_maxSize)
		{
			obj.m_arr[i] = 0;
			i++;
		}

		return obj;
	endmethod
	
	method destroy takes void returns void
		int i = 0;
		while (i < m_size)
		{
			if (m_arr[i] != 0)
			{
				m_arr[i].destroy();
			}
			i++;
		}
		
		this.deallocate();
	endmethod
	
	method GetBottom takes void returns StructuresSnapshot
		if (m_size == 0)
		{
			return 0;
		}
		return m_arr[0];
	endmethod
	
	method Push takes StructuresSnapshot ss returns void
		if (m_maxSize <= 0)
		{
			return;
		}
	
		int i;
		if (m_size >= m_maxSize)
		{
			i = 0;
			while (i < (m_size -1))
			{
				m_arr[i] = m_arr[i+1];
				i++;
			}
			if (m_arr[m_size - 1] != 0)
			{
				m_arr[m_size - 1].destroy();
			}
			m_arr[m_size - 1] = ss;
		}
		else
		{
			m_arr[m_size] = ss;
			m_size++;
		}
	endmethod
	
	method Pop takes nothing returns StructuresSnapshot
		if (m_size == 0)
		{
			return 0;
		}
		
		int obj = m_arr[m_size - 1];
		m_arr[m_size - 1] = 0;
		m_size--;
		return obj;
	endmethod
	
};
Почему там где я отметил комментарием в методе Restore - this равен нулю?
Как правило снапшот беру через GetBottom

Принятый ответ

Drulia_san, посмотрел код, если this есть 0 в обычном методе, то это значит, что там где ты вызываешь Restore для StructuresSnapshot ты передаешь 0.
call obj.Restore()  // obj равен 0, а его тип есть StructuresSnapshot.
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
28
5 лет назад
0
Режим дебага включён у vJass?
0
16
5 лет назад
0
PT153:
Режим дебага включён у vJass?
Неа
0
28
5 лет назад
0
Включи, у тебя может быть кончился лимит на объекты класса.
1
16
5 лет назад
1
PT153:
Включи, у тебя может быть кончился лимит на объекты класса.
Я прогнал карту со включенным дебагом, никаких новых сообщений не появилось. Да я на калькуляторе считал, там в хуждшем случае 4-5 тысяч объектов на карте может быть таких одновременно, а максимум вроде как 8
Но здесь и тысячи нет, лимит вряд ли превышается...
0
28
5 лет назад
0
Drulia_san, посмотрел код, если this есть 0 в обычном методе, то это значит, что там где ты вызываешь Restore для StructuresSnapshot ты передаешь 0.
call obj.Restore()  // obj равен 0, а его тип есть StructuresSnapshot.
Принятый ответ
1
16
5 лет назад
1
PT153:
Drulia_san, посмотрел код, если this есть 0 в обычном методе, то это значит, что там где ты вызываешь Restore для StructuresSnapshot ты передаешь 0.
call obj.Restore()  // obj равен 0, а его тип есть StructuresSnapshot.
Действительно. Объект вообще не создлавался, оказывается строчка obj.hNoBar = g_HNoBarracks; в конструкторе StructureSnapshot присваивала не инициализированную глобалку, из-за чего падала вся эта "башня" из объектов)
0
28
5 лет назад
0
Drulia_san, поставь себе нормальный pjass.exe, оно подобные ошибки видит.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.