Hi CarmineZ, i included new messages in the protocol "network.py"...
NetMessage("Sv_TileCreate", [
NetIntAny("m_X"),
NetIntAny("m_Y"),
NetIntAny("m_ITile"),
NetIntAny("m_State"),
NetIntAny("m_Col"),
]),
NetMessage("Sv_TileDestroy", [
NetIntAny("m_X"),
NetIntAny("m_Y"),
]),
NetMessage("Sv_TileChangeExt", [
NetIntAny("m_Index"),
NetIntAny("m_X"),
NetIntAny("m_Y"),
NetIntAny("m_ITile"),
NetIntAny("m_State"),
NetIntAny("m_Col"),
NetIntRange("m_Act", 'TILE_DESTROY', 'TILE_CREATE'),
]),
When Destroy...
if (str_comp_nocase(GameServer()->GameType(), "MineTee") == 0 && g_Config.m_SvGameMode == 0)
{
vec2 colTilePos = ProjStartPos+Direction * 80.0f;
if (GameServer()->Collision()->IntersectLine(ProjStartPos, colTilePos, &colTilePos, 0x0, false))
{
vec2 finishPosPost = colTilePos+Direction * 16.0f;
if (GameServer()->Collision()->GetCollisionAt(finishPosPost.x, finishPosPost.y) == CCollision::COLFLAG_SOLID)
{
int TIndex = -1;
if ((TIndex = GameServer()->Collision()->DestroyTile(finishPosPost)) > 0)
{
CNetMsg_Sv_TileDestroy TileInfo;
TileInfo.m_X = static_cast<int>(finishPosPost.x/32.0f);
TileInfo.m_Y = static_cast<int>(finishPosPost.y/32.0f);
Server()->SendPackMsg(&TileInfo, MSGFLAG_VITAL, -1);
CPickup *pPickup = new CPickup(&GameServer()->m_World, POWERUP_BLOCK, TIndex);
pPickup->m_Pos = vec2(TileInfo.m_X*32.0f + 8.0f, TileInfo.m_Y*32.0f + 8.0f);
GameServer()->CreateSound(m_Pos, SOUND_DESTROY_BLOCK);
}
Hits++;
}
}
}
When Client get the message:
if(MsgType == NETMSGTYPE_SV_TILEDESTROY)
{
CNetMsg_Sv_TileDestroy *pMsg = (CNetMsg_Sv_TileDestroy *)pRawMsg;
vec2 Pos = vec2(pMsg->m_X, pMsg->m_Y);
if (Pos.x >= Layers()->MineTeeLayer()->m_Width-1 || Pos.x <= 0 || Pos.y >= Layers()->MineTeeLayer()->m_Height-1 || Pos.y <= 0)
return;
Layers()->DestroyTile(Pos);
m_pClient->m_pEffects->BlockDestroy(vec2(Pos.x*32.0f, Pos.y*32.0f));
}
When build...
void CCharacter::Construct()
{
if(m_ReloadTimer != 0)
return;
bool Builded = false;
int ActiveBlock = (m_ActiveWeapon - NUM_WEAPONS) % NUM_BLOCKS;
DoWeaponSwitch();
vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));
// check if we gonna fire
bool WillFire = false;
if(CountInput(m_LatestPrevInput.m_Fire, m_LatestInput.m_Fire).m_Presses)
WillFire = true;
if(!WillFire)
return;
vec2 ProjStartPos= m_Pos + Direction * 38.0f;
vec2 colTilePos = ProjStartPos+Direction * 120.0f;
CNetMsg_Sv_TileCreate TileInfo;
if (m_pPlayer->m_PlayerFlags&PLAYERFLAG_BGPAINT)
{
CNetMsg_Sv_TileCreate TileInfo;
TileInfo.m_X = static_cast<int>((m_Pos.x+m_LatestInput.m_TargetX)/32.0f);
TileInfo.m_Y = static_cast<int>((m_Pos.y+m_LatestInput.m_TargetY)/32.0f);
TileInfo.m_ITile = ActiveBlock;
TileInfo.m_Col = true;
TileInfo.m_State = (m_pPlayer->m_PlayerFlags&PLAYERFLAG_BGPAINT);
Server()->SendPackMsg(&TileInfo, MSGFLAG_VITAL, -1);
GameServer()->Collision()->CreateTile(vec2((m_Pos.x+m_LatestInput.m_TargetX), (m_Pos.y+m_LatestInput.m_TargetY)), ActiveBlock, 0, 1);
GameServer()->CreateSound(m_Pos, SOUND_DESTROY_BLOCK);
Builded = true;
}
else if (GameServer()->Collision()->IntersectLine(ProjStartPos, colTilePos, &colTilePos, 0x0, false))
{
vec2 finishPosPost = colTilePos-Direction * 16.0f;
if (GameServer()->Collision()->GetCollisionAt(finishPosPost.x, finishPosPost.y) != CCollision::COLFLAG_SOLID)
{
CNetMsg_Sv_TileCreate TileInfo;
TileInfo.m_X = static_cast<int>(finishPosPost.x/32.0f);
TileInfo.m_Y = static_cast<int>(finishPosPost.y/32.0f);
TileInfo.m_ITile = ActiveBlock;
TileInfo.m_Col = true;
TileInfo.m_State = (m_pPlayer->m_PlayerFlags&PLAYERFLAG_BGPAINT);
//Check player stuck
for (int i=0; i<MAX_CLIENTS; i++)
{
if (!GameServer()->m_apPlayers[i])
continue;
CCharacter *pChar = GameServer()->m_apPlayers[i]->GetCharacter();
if (!pChar || !pChar->IsAlive())
continue;
if (vec2(static_cast<int>(pChar->m_Pos.x/32), static_cast<int>(pChar->m_Pos.y/32)) == vec2(TileInfo.m_X, TileInfo.m_Y))
return;
}
//check blocks
unsigned char DenyBlocks[] = { BLOCK_LUZ };
CTile *pMTTiles = (CTile *)GameServer()->Layers()->Map()->GetData(GameServer()->Layers()->MineTeeLayer()->m_Data);
for (int i=0; i<sizeof(DenyBlocks); i++)
{
if (ActiveBlock != DenyBlocks[i])
continue;
int Index = (TileInfo.m_Y-1)*GameServer()->Layers()->MineTeeLayer()->m_Width+TileInfo.m_X;
if (pMTTiles[Index].m_Index == DenyBlocks[i])
return;
Index = (TileInfo.m_Y+1)*GameServer()->Layers()->MineTeeLayer()->m_Width+TileInfo.m_X;
if (pMTTiles[Index].m_Index == DenyBlocks[i])
return;
Index = TileInfo.m_Y*GameServer()->Layers()->MineTeeLayer()->m_Width+(TileInfo.m_X-1);
if (pMTTiles[Index].m_Index == DenyBlocks[i])
return;
Index = TileInfo.m_Y*GameServer()->Layers()->MineTeeLayer()->m_Width+(TileInfo.m_X+1);
if (pMTTiles[Index].m_Index == DenyBlocks[i])
return;
Index = (TileInfo.m_Y-1)*GameServer()->Layers()->MineTeeLayer()->m_Width+(TileInfo.m_X-1);
if (pMTTiles[Index].m_Index == DenyBlocks[i])
return;
Index = (TileInfo.m_Y+1)*GameServer()->Layers()->MineTeeLayer()->m_Width+(TileInfo.m_X+1);
if (pMTTiles[Index].m_Index == DenyBlocks[i])
return;
Index = (TileInfo.m_Y+1)*GameServer()->Layers()->MineTeeLayer()->m_Width+(TileInfo.m_X-1);
if (pMTTiles[Index].m_Index == DenyBlocks[i])
return;
Index = (TileInfo.m_Y-1)*GameServer()->Layers()->MineTeeLayer()->m_Width+(TileInfo.m_X+1);
if (pMTTiles[Index].m_Index == DenyBlocks[i])
return;
}
if (distance(m_Pos, finishPosPost) >= 42.0f)
{
Server()->SendPackMsg(&TileInfo, MSGFLAG_VITAL, -1);
GameServer()->Collision()->CreateTile(finishPosPost, ActiveBlock, CCollision::COLFLAG_SOLID, 0);
GameServer()->CreateSound(m_Pos, SOUND_DESTROY_BLOCK);
Builded = true;
}
}
}
if (Builded)
{
m_aBlocks[ActiveBlock].m_Amount--;
if(m_aBlocks[ActiveBlock].m_Amount == 0)
{
m_aBlocks[ActiveBlock].m_Got = false;
ActiveBlock=1;
while (!m_aBlocks[ActiveBlock].m_Got)
{
if (ActiveBlock >= NUM_BLOCKS)
break;
ActiveBlock++;
}
if (ActiveBlock >= NUM_BLOCKS)
SetWeapon(WEAPON_HAMMER);
else
SetWeapon(NUM_WEAPONS+ActiveBlock);
}
UpdateInventory();
}
}
When Client get TILE_CREATE message...
else if(MsgType == NETMSGTYPE_SV_TILECREATE)
{
CNetMsg_Sv_TileCreate *pMsg = (CNetMsg_Sv_TileCreate *)pRawMsg;
vec2 Pos = vec2(pMsg->m_X, pMsg->m_Y);
if (Pos.x >= Layers()->MineTeeLayer()->m_Width-1 || Pos.x <= 0 || Pos.y >= Layers()->MineTeeLayer()->m_Height-1 || Pos.y <= 0)
return;
Layers()->CreateTile(Pos, pMsg->m_ITile, pMsg->m_Col, pMsg->m_State);
}
CreateTile Function "Collision.cpp":
void CCollision::CreateTile(vec2 Pos, int ITile, int Type, int State)
{
if (!m_pLayers->MineTeeLayer())
return;
Pos = vec2(static_cast<int>(Pos.x/32.0f), static_cast<int>(Pos.y/32.0f));
if (Pos.x >= m_pLayers->MineTeeLayer()->m_Width-1 || Pos.x <= 0 || Pos.y >= m_pLayers->MineTeeLayer()->m_Height-1 || Pos.y <= 0)
return;
//MineTee Layer
if (State == 0)
{
int MTIndex = static_cast<int>(Pos.y*m_Width+Pos.x);
CTile *pMTTiles = (CTile *)m_pLayers->Map()->GetData(m_pLayers->MineTeeLayer()->m_Data);
pMTTiles[MTIndex].m_Flags = 0x0;
pMTTiles[MTIndex].m_Index = ITile;
}
else
{
int MTIndex = static_cast<int>(Pos.y*m_Width+Pos.x);
CTile *pMTBGTiles = (CTile *)m_pLayers->Map()->GetData(m_pLayers->MineTeeBGLayer()->m_Data);
pMTBGTiles[MTIndex].m_Flags = 0x0;
pMTBGTiles[MTIndex].m_Index = ITile;
}
//Game Layer
int Index = Pos.y*m_pLayers->MineTeeLayer()->m_Width+Pos.x;
m_pTiles[Index].m_Flags = 0x0;
m_pTiles[Index].m_Index = Type;
//Buffer it
CNetMsg_Sv_TileChangeExt TileChange;
TileChange.m_Act = TILE_CREATE;
TileChange.m_X = static_cast<int>(Pos.x);
TileChange.m_Y = static_cast<int>(Pos.y);
TileChange.m_ITile = ITile;
if (Type&CCollision::COLFLAG_SOLID)
TileChange.m_Col = 1;
else
TileChange.m_Col = 0;
TileChange.m_State = State;
if (!CheckTileChangeBuffer(TileChange))
m_pLayers->m_BuffNetTileChange.push_back(TileChange);
}
TileDestroy "Collision.cpp":
int CCollision::DestroyTile(vec2 Pos)
{
int LIndex = -1;
if (!m_pLayers->MineTeeLayer())
return LIndex;
Pos = vec2(static_cast<int>(Pos.x/32.0f), static_cast<int>(Pos.y/32.0f));
if (Pos.x >= m_Width-1 || Pos.x <= 0 || Pos.y >= m_Height-1 || Pos.y <= 0)
return LIndex;
//MineTee Layer
int MTIndex = static_cast<int>(Pos.y*m_pLayers->MineTeeLayer()->m_Width+Pos.x);
CTile *pMTTiles = (CTile *)m_pLayers->Map()->GetData(m_pLayers->MineTeeLayer()->m_Data);
LIndex = pMTTiles[MTIndex].m_Index;
pMTTiles[MTIndex].m_Flags = 0x0;
pMTTiles[MTIndex].m_Index = 0;
//GameLayer
int Index = static_cast<int>(Pos.y*m_Width+Pos.x);
m_pTiles[Index].m_Flags = 0x0;
m_pTiles[Index].m_Index = 0;
//Buffer it
CNetMsg_Sv_TileChangeExt TileChange;
TileChange.m_Act = TILE_DESTROY;
TileChange.m_X = static_cast<int>(Pos.x);
TileChange.m_Y = static_cast<int>(Pos.y);
TileChange.m_ITile = 0;
TileChange.m_State = 0;
if (!CheckTileChangeBuffer(TileChange))
m_pLayers->m_BuffNetTileChange.push_back(TileChange);
return LIndex;
}
CreateTile "layers.cpp":
void CLayers::CreateTile(vec2 Pos, int ITile, bool Coll, int State)
{
if (!MineTeeLayer())
return;
CMapItemLayerTilemap *pTMap = 0x0;
if (State)
pTMap = MineTeeBGLayer();
else
pTMap = MineTeeLayer();
if (pTMap)
{
CTile *pTiles = (CTile *)Map()->GetData(pTMap->m_Data);
int Index = static_cast<int>(Pos.y*pTMap->m_Width+Pos.x);
pTiles[Index].m_Flags = 0x0;
pTiles[Index].m_Index = ITile;
}
//Game Layer
if (Coll)
{
CMapItemLayerTilemap *pTMapGame = GameLayer();
CTile *pTilesGame = (CTile *)Map()->GetData(pTMapGame->m_Data);
int Index = static_cast<int>(Pos.y*pTMapGame->m_Width+Pos.x);
pTilesGame[Index].m_Flags = 0x0;
pTilesGame[Index].m_Index = (!State)?TILE_SOLID:0;
}
}
DestroyTile "layers.cpp":
int CLayers::DestroyTile(vec2 Pos)
{
int ITile = 0;
CMapItemLayerTilemap *pTMap = MineTeeLayer();
CTile *pTiles = (CTile *)Map()->GetData(pTMap->m_Data);
int Index = static_cast<int>(Pos.y*pTMap->m_Width+Pos.x);
ITile = pTiles[Index].m_Index;
pTiles[Index].m_Flags = 0x0;
pTiles[Index].m_Index = 0;
//Game Layer
CMapItemLayerTilemap *pTMapGame = GameLayer();
CTile *pTilesGame = (CTile *)Map()->GetData(pTMapGame->m_Data);
Index = static_cast<int>(Pos.y*pTMapGame->m_Width+Pos.x);
pTilesGame[Index].m_Flags = 0x0;
pTilesGame[Index].m_Index = 0;
return ITile;
}
-----
And... in minetee layers i set m_Skip variable to 0 in all Tiles...