Phobos icon indicating copy to clipboard operation
Phobos copied to clipboard

Trigger owner can set as player of multiplayer game map

Open ststl-s opened this issue 3 years ago • 6 comments

In a multiplayer map, set trigger owner as '4475'-'4482' is player@A-player@G. If player nonexist, trigger will be desotroyed.

ststl-s avatar Sep 08 '22 11:09 ststl-s

Nightly build for this pull request:

github-actions[bot] avatar Sep 08 '22 11:09 github-actions[bot]

The current approach is not quite good in fact, we don't need a std::map for just 8 fixed-size players.

secsome avatar Sep 09 '22 14:09 secsome

The current approach is not quite good in fact, we don't need a std::map for just 8 fixed-size players.

It is a mapping from TriggerType to MP. Is there any better way?

ststl-s avatar Sep 10 '22 07:09 ststl-s

// PR #746: [QOL] Trigger owner can set as player of multiplayer game map.
DEFINE_HOOK(0x7272B5, TriggerTypeClass_FillIn_HouseType, 0x6)
{
	GET(int, nIndex, EAX);

	// Only if the house wasn't found
	if (nIndex == -1)
	{
		GET(const char*, pString, ECX);
		nIndex = HouseClass::GetPlayerAtFromString(pString);
		if (nIndex == -1)
		{
			nIndex = atoi(pString);

			if (nIndex == -1)
				nIndex = 0; // process it like <none>
		}

		if (HouseClass::IsPlayerAtType(nIndex))
		{
			if (auto pHouse = HouseClass::FindByPlayerAt(nIndex))
				nIndex = pHouse->Type->ArrayIndex;
		}
		else
			nIndex = 0;

		R->EAX(nIndex);
	}

	return 0;
}

secsome avatar Sep 16 '22 12:09 secsome

// PR #746: [QOL] Trigger owner can set as player of multiplayer game map.
DEFINE_HOOK(0x7272B5, TriggerTypeClass_FillIn_HouseType, 0x6)
{
	GET(int, nIndex, EAX);

	// Only if the house wasn't found
	if (nIndex == -1)
	{
		GET(const char*, pString, ECX);
		nIndex = HouseClass::GetPlayerAtFromString(pString);
		if (nIndex == -1)
		{
			nIndex = atoi(pString);

			if (nIndex == -1)
				nIndex = 0; // process it like <none>
		}

		if (HouseClass::IsPlayerAtType(nIndex))
		{
			if (auto pHouse = HouseClass::FindByPlayerAt(nIndex))
				nIndex = pHouse->Type->ArrayIndex;
		}
		else
			nIndex = 0;

		R->EAX(nIndex);
	}

	return 0;
}

I don't quite understand this method. Two players from the same country can only find the first player to select this country through HouseClass:: FindByCountryIndex, so I need to establish a corresponding relationship between TriggerType and Player. The TriggerType's member is HouseTypeClass*, and it is not sure which player it is. Unless I directly assign an MP reference like 4475 to this pointer, although this can be achieved, it seems that it is not a good practice to assign integer values to pointer types.

ststl-s avatar Sep 17 '22 08:09 ststl-s

我不太能理解这个。。据我所知,多人游戏里如果按照国家类型只能找到第一个选择了这个国家的玩家,所以我才需要建立一个TriggerType 到玩家的对应关系,而TriggerType的成员只有一个HouseTypeClass* House,这样没法对应到具体的一个玩家上。当然也可以直接把4475这些值赋值到这个HouseTypeClass* House上并且保留TriggerClass::FireActionsTriggerClass::RaiseEvent中关于寻找House实体的钩子,这样可以省去额外用一个map或者其它什么容器的麻烦,只是觉得把整形赋值给指针不太好。

ststl-s avatar Sep 17 '22 08:09 ststl-s