bool CModAPI_Component_Items::ProcessEvent(int Type, CNetEvent_Common* pEvent) { switch(Type) { case NETEVENTTYPE_MODAPI_ANIMATEDTEXT: { CNetEvent_ModAPI_AnimatedText* pTextEvent = (CNetEvent_ModAPI_AnimatedText*) pEvent; if(pTextEvent->m_ItemLayer != GetLayer()) return false; CTextEventState EventState; EventState.m_Pos.x = static_cast<float>(pTextEvent->m_X); EventState.m_Pos.y = static_cast<float>(pTextEvent->m_Y); EventState.m_Size = static_cast<float>(pTextEvent->m_Size); EventState.m_Color = ModAPI_IntToColor(pTextEvent->m_Color); EventState.m_Alignment = pTextEvent->m_Alignment; IntsToStr(pTextEvent->m_aText, 16, &EventState.m_aText[0]); EventState.m_AnimationId = pTextEvent->m_AnimationId; EventState.m_Offset.x = static_cast<float>(pTextEvent->m_OffsetX); EventState.m_Offset.y = static_cast<float>(pTextEvent->m_OffsetY); EventState.m_Duration = static_cast<float>(pTextEvent->m_Duration)/1000.f; EventState.m_Time = 0.f; m_TextEvent.push_back(EventState); } return true; } }
void CGhost::InitRenderInfos(CGhostItem *pGhost) { char aSkinName[64]; IntsToStr(&pGhost->m_Skin.m_Skin0, 6, aSkinName); CTeeRenderInfo *pRenderInfo = &pGhost->m_RenderInfo; int SkinId = m_pClient->m_pSkins->Find(aSkinName); if(pGhost->m_Skin.m_UseCustomColor) { pRenderInfo->m_Texture = m_pClient->m_pSkins->Get(SkinId)->m_ColorTexture; pRenderInfo->m_ColorBody = m_pClient->m_pSkins->GetColorV4(pGhost->m_Skin.m_ColorBody); pRenderInfo->m_ColorFeet = m_pClient->m_pSkins->GetColorV4(pGhost->m_Skin.m_ColorFeet); } else { pRenderInfo->m_Texture = m_pClient->m_pSkins->Get(SkinId)->m_OrgTexture; pRenderInfo->m_ColorBody = vec4(1, 1, 1, 1); pRenderInfo->m_ColorFeet = vec4(1, 1, 1, 1); } pRenderInfo->m_ColorBody.a = 0.5f; pRenderInfo->m_ColorFeet.a = 0.5f; pRenderInfo->m_Size = 64; }
void CModAPI_Component_Items::RenderModAPIAnimatedTextCharacter(const CNetObj_ModAPI_AnimatedTextCharacter *pPrev, const CNetObj_ModAPI_AnimatedTextCharacter *pCurrent) { if(pCurrent->m_ItemLayer != GetLayer()) return; if(!TextRender()||!m_pClient->m_Snap.m_aCharacters[pCurrent->m_ClientId].m_Active) return; vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick()); vec2 Offset = mix(vec2(pPrev->m_OffsetX, pPrev->m_OffsetY), vec2(pCurrent->m_OffsetX, pCurrent->m_OffsetY), Client()->IntraGameTick()); if(m_pClient->m_LocalClientID != -1 && m_pClient->m_LocalClientID == pCurrent->m_ClientId) { Pos = m_pClient->m_LocalCharacterPos + Pos; } else { CNetObj_Character PrevChar = m_pClient->m_Snap.m_aCharacters[pCurrent->m_ClientId].m_Prev; CNetObj_Character CurChar = m_pClient->m_Snap.m_aCharacters[pCurrent->m_ClientId].m_Cur; Pos = mix(vec2(PrevChar.m_X, PrevChar.m_Y), vec2(CurChar.m_X, CurChar.m_Y), Client()->IntraGameTick()) + Pos; } float Time = Client()->GameTick() + Client()->IntraGameTick() - pCurrent->m_StartTick; Time = (Time/static_cast<float>(SERVER_TICK_SPEED)) * 1000.0f; Time = Time / (static_cast<float>(pCurrent->m_Duration)/1000.f); char aText[64]; IntsToStr(pCurrent->m_aText, 16, &aText[0]); ModAPIGraphics()->DrawAnimatedText(TextRender(), aText, Pos, ModAPI_IntToColor(pCurrent->m_Color), pCurrent->m_Size, pCurrent->m_Alignment, pCurrent->m_AnimationId, Time, Offset); }
void CModAPI_Component_Items::RenderModAPIText(const CNetObj_ModAPI_Text *pPrev, const CNetObj_ModAPI_Text *pCurrent) { if(pCurrent->m_ItemLayer != GetLayer()) return; if(!TextRender()) return; vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick()); char aText[64]; IntsToStr(pCurrent->m_aText, 16, &aText[0]); ModAPIGraphics()->DrawText(TextRender(), aText, Pos, ModAPI_IntToColor(pCurrent->m_Color), pCurrent->m_Size, pCurrent->m_Alignment); }
void CComponent_Items::RenderText(const CNetObj_TU_Text *pPrev, const CNetObj_TU_Text *pCurrent) { if(pCurrent->m_ItemLayer != GetLayer()) return; if(!TextRender()) return; vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick()); char aText[64]; IntsToStr(pCurrent->m_aText, 16, &aText[0]); TUKernel()->AssetsRenderer()->DrawText(aText, Pos, tu::IntToColor(pCurrent->m_Color), pCurrent->m_Size, pCurrent->m_Alignment); }
void CModAPI_Component_Items::RenderModAPIAnimatedText(const CNetObj_ModAPI_AnimatedText *pPrev, const CNetObj_ModAPI_AnimatedText *pCurrent) { if(pCurrent->m_ItemLayer != GetLayer()) return; if(!TextRender()) return; vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick()); vec2 Offset = mix(vec2(pPrev->m_OffsetX, pPrev->m_OffsetY), vec2(pCurrent->m_OffsetX, pCurrent->m_OffsetY), Client()->IntraGameTick()); float Time = Client()->GameTick() + Client()->IntraGameTick() - pCurrent->m_StartTick; Time = (Time/static_cast<float>(SERVER_TICK_SPEED)) * 1000.0f; Time = Time / (static_cast<float>(pCurrent->m_Duration)/1000.f); char aText[64]; IntsToStr(pCurrent->m_aText, 16, &aText[0]); ModAPIGraphics()->DrawAnimatedText(TextRender(), aText, Pos, ModAPI_IntToColor(pCurrent->m_Color), pCurrent->m_Size, pCurrent->m_Alignment, pCurrent->m_AnimationId, Time, Offset); }
void CModAPI_Component_Items::RenderModAPITextCharacter(const CNetObj_ModAPI_TextCharacter *pPrev, const CNetObj_ModAPI_TextCharacter *pCurrent) { if(pCurrent->m_ItemLayer != GetLayer()) return; if(!TextRender()||!m_pClient->m_Snap.m_aCharacters[pCurrent->m_ClientId].m_Active) return; vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick()); if(m_pClient->m_LocalClientID != -1 && m_pClient->m_LocalClientID == pCurrent->m_ClientId) { Pos = m_pClient->m_LocalCharacterPos + Pos; } else { CNetObj_Character PrevChar = m_pClient->m_Snap.m_aCharacters[pCurrent->m_ClientId].m_Prev; CNetObj_Character CurChar = m_pClient->m_Snap.m_aCharacters[pCurrent->m_ClientId].m_Cur; Pos = mix(vec2(PrevChar.m_X, PrevChar.m_Y), vec2(CurChar.m_X, CurChar.m_Y), Client()->IntraGameTick()) + Pos; } char aText[64]; IntsToStr(pCurrent->m_aText, 16, &aText[0]); ModAPIGraphics()->DrawText(TextRender(), aText, Pos, ModAPI_IntToColor(pCurrent->m_Color), pCurrent->m_Size, pCurrent->m_Alignment); }
void CGameClient::OnNewSnapshot() { m_NewTick = true; // clear out the invalid pointers mem_zero(&g_GameClient.m_Snap, sizeof(g_GameClient.m_Snap)); m_Snap.m_LocalClientID = -1; // secure snapshot { int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int Index = 0; Index < Num; Index++) { IClient::CSnapItem Item; void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, Index, &Item); if(m_NetObjHandler.ValidateObj(Item.m_Type, pData, Item.m_DataSize) != 0) { if(g_Config.m_Debug) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "invalidated index=%d type=%d (%s) size=%d id=%d", Index, Item.m_Type, m_NetObjHandler.GetObjName(Item.m_Type), Item.m_DataSize, Item.m_ID); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); } Client()->SnapInvalidateItem(IClient::SNAP_CURRENT, Index); } } } ProcessEvents(); if(g_Config.m_DbgStress) { if((Client()->GameTick()%100) == 0) { char aMessage[64]; int MsgLen = rand()%(sizeof(aMessage)-1); for(int i = 0; i < MsgLen; i++) aMessage[i] = 'a'+(rand()%('z'-'a')); aMessage[MsgLen] = 0; CNetMsg_Cl_Say Msg; Msg.m_Team = rand()&1; Msg.m_pMessage = aMessage; Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } } // go trough all the items in the snapshot and gather the info we want { m_Snap.m_aTeamSize[TEAM_RED] = m_Snap.m_aTeamSize[TEAM_BLUE] = 0; int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int i = 0; i < Num; i++) { IClient::CSnapItem Item; const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); if(Item.m_Type == NETOBJTYPE_CLIENTINFO) { const CNetObj_ClientInfo *pInfo = (const CNetObj_ClientInfo *)pData; int ClientID = Item.m_ID; IntsToStr(&pInfo->m_Name0, 4, m_aClients[ClientID].m_aName); IntsToStr(&pInfo->m_Clan0, 3, m_aClients[ClientID].m_aClan); m_aClients[ClientID].m_Country = pInfo->m_Country; IntsToStr(&pInfo->m_Skin0, 6, m_aClients[ClientID].m_aSkinName); m_aClients[ClientID].m_UseCustomColor = pInfo->m_UseCustomColor; m_aClients[ClientID].m_ColorBody = pInfo->m_ColorBody; m_aClients[ClientID].m_ColorFeet = pInfo->m_ColorFeet; // prepare the info if(m_aClients[ClientID].m_aSkinName[0] == 'x' || m_aClients[ClientID].m_aSkinName[1] == '_') str_copy(m_aClients[ClientID].m_aSkinName, "default", 64); m_aClients[ClientID].m_SkinInfo.m_ColorBody = m_pSkins->GetColorV4(m_aClients[ClientID].m_ColorBody); m_aClients[ClientID].m_SkinInfo.m_ColorFeet = m_pSkins->GetColorV4(m_aClients[ClientID].m_ColorFeet); m_aClients[ClientID].m_SkinInfo.m_Size = 64; // find new skin m_aClients[ClientID].m_SkinID = g_GameClient.m_pSkins->Find(m_aClients[ClientID].m_aSkinName); if(m_aClients[ClientID].m_SkinID < 0) { m_aClients[ClientID].m_SkinID = g_GameClient.m_pSkins->Find("default"); if(m_aClients[ClientID].m_SkinID < 0) m_aClients[ClientID].m_SkinID = 0; } if(m_aClients[ClientID].m_UseCustomColor) m_aClients[ClientID].m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(m_aClients[ClientID].m_SkinID)->m_ColorTexture; else { m_aClients[ClientID].m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(m_aClients[ClientID].m_SkinID)->m_OrgTexture; m_aClients[ClientID].m_SkinInfo.m_ColorBody = vec4(1,1,1,1); m_aClients[ClientID].m_SkinInfo.m_ColorFeet = vec4(1,1,1,1); } m_aClients[ClientID].UpdateRenderInfo(); } else if(Item.m_Type == NETOBJTYPE_PLAYERINFO) { const CNetObj_PlayerInfo *pInfo = (const CNetObj_PlayerInfo *)pData; m_aClients[pInfo->m_ClientID].m_Team = pInfo->m_Team; m_aClients[pInfo->m_ClientID].m_Active = true; m_Snap.m_paPlayerInfos[pInfo->m_ClientID] = pInfo; m_Snap.m_NumPlayers++; if(pInfo->m_Local) { m_Snap.m_LocalClientID = Item.m_ID; m_Snap.m_pLocalInfo = pInfo; if(pInfo->m_Team == TEAM_SPECTATORS) { m_Snap.m_SpecInfo.m_Active = true; m_Snap.m_SpecInfo.m_SpectatorID = SPEC_FREEVIEW; } } // calculate team-balance if(pInfo->m_Team != TEAM_SPECTATORS) m_Snap.m_aTeamSize[pInfo->m_Team]++; } else if(Item.m_Type == NETOBJTYPE_CHARACTER) { const void *pOld = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_CHARACTER, Item.m_ID); m_Snap.m_aCharacters[Item.m_ID].m_Cur = *((const CNetObj_Character *)pData); if(pOld) { m_Snap.m_aCharacters[Item.m_ID].m_Active = true; m_Snap.m_aCharacters[Item.m_ID].m_Prev = *((const CNetObj_Character *)pOld); if(m_Snap.m_aCharacters[Item.m_ID].m_Prev.m_Tick) Evolve(&m_Snap.m_aCharacters[Item.m_ID].m_Prev, Client()->PrevGameTick()); if(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_Tick) Evolve(&m_Snap.m_aCharacters[Item.m_ID].m_Cur, Client()->GameTick()); } } else if(Item.m_Type == NETOBJTYPE_SPECTATORINFO) { m_Snap.m_pSpectatorInfo = (const CNetObj_SpectatorInfo *)pData; m_Snap.m_pPrevSpectatorInfo = (const CNetObj_SpectatorInfo *)Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_SPECTATORINFO, Item.m_ID); m_Snap.m_SpecInfo.m_SpectatorID = m_Snap.m_pSpectatorInfo->m_SpectatorID; } else if(Item.m_Type == NETOBJTYPE_GAMEINFO) { static bool s_GameOver = 0; m_Snap.m_pGameInfoObj = (const CNetObj_GameInfo *)pData; if(!s_GameOver && m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER) OnGameOver(); else if(s_GameOver && !(m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)) OnStartGame(); s_GameOver = m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER; } else if(Item.m_Type == NETOBJTYPE_GAMEDATA) { m_Snap.m_pGameDataObj = (const CNetObj_GameData *)pData; m_Snap.m_GameDataSnapID = Item.m_ID; if(m_Snap.m_pGameDataObj->m_FlagCarrierRed == FLAG_TAKEN) { if(m_FlagDropTick[TEAM_RED] == 0) m_FlagDropTick[TEAM_RED] = Client()->GameTick(); } else if(m_FlagDropTick[TEAM_RED] != 0) m_FlagDropTick[TEAM_RED] = 0; if(m_Snap.m_pGameDataObj->m_FlagCarrierBlue == FLAG_TAKEN) { if(m_FlagDropTick[TEAM_BLUE] == 0) m_FlagDropTick[TEAM_BLUE] = Client()->GameTick(); } else if(m_FlagDropTick[TEAM_BLUE] != 0) m_FlagDropTick[TEAM_BLUE] = 0; } else if(Item.m_Type == NETOBJTYPE_FLAG) m_Snap.m_paFlags[Item.m_ID%2] = (const CNetObj_Flag *)pData; } } // setup local pointers if(m_Snap.m_LocalClientID >= 0) { CSnapState::CCharacterInfo *c = &m_Snap.m_aCharacters[m_Snap.m_LocalClientID]; if(c->m_Active) { m_Snap.m_pLocalCharacter = &c->m_Cur; m_Snap.m_pLocalPrevCharacter = &c->m_Prev; m_LocalCharacterPos = vec2(m_Snap.m_pLocalCharacter->m_X, m_Snap.m_pLocalCharacter->m_Y); } else if(Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_CHARACTER, m_Snap.m_LocalClientID)) { // player died m_pControls->OnPlayerDeath(); } } else { m_Snap.m_SpecInfo.m_Active = true; if(Client()->State() == IClient::STATE_DEMOPLAYBACK && DemoPlayer()->GetDemoType() == IDemoPlayer::DEMOTYPE_SERVER && m_DemoSpecID != SPEC_FREEVIEW && m_Snap.m_aCharacters[m_DemoSpecID].m_Active) m_Snap.m_SpecInfo.m_SpectatorID = m_DemoSpecID; else m_Snap.m_SpecInfo.m_SpectatorID = SPEC_FREEVIEW; } // clear out unneeded client data for(int i = 0; i < MAX_CLIENTS; ++i) { if(!m_Snap.m_paPlayerInfos[i] && m_aClients[i].m_Active) m_aClients[i].Reset(); } // update friend state for(int i = 0; i < MAX_CLIENTS; ++i) { if(i == m_Snap.m_LocalClientID || !m_Snap.m_paPlayerInfos[i] || !Friends()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)) m_aClients[i].m_Friend = false; else m_aClients[i].m_Friend = true; } // sort player infos by score mem_copy(m_Snap.m_paInfoByScore, m_Snap.m_paPlayerInfos, sizeof(m_Snap.m_paInfoByScore)); for(int k = 0; k < MAX_CLIENTS-1; k++) // ffs, bubblesort { for(int i = 0; i < MAX_CLIENTS-k-1; i++) { if(m_Snap.m_paInfoByScore[i+1] && (!m_Snap.m_paInfoByScore[i] || m_Snap.m_paInfoByScore[i]->m_Score < m_Snap.m_paInfoByScore[i+1]->m_Score)) { const CNetObj_PlayerInfo *pTmp = m_Snap.m_paInfoByScore[i]; m_Snap.m_paInfoByScore[i] = m_Snap.m_paInfoByScore[i+1]; m_Snap.m_paInfoByScore[i+1] = pTmp; } } } // sort player infos by team int Teams[3] = { TEAM_RED, TEAM_BLUE, TEAM_SPECTATORS }; int Index = 0; for(int Team = 0; Team < 3; ++Team) { for(int i = 0; i < MAX_CLIENTS && Index < MAX_CLIENTS; ++i) { if(m_Snap.m_paPlayerInfos[i] && m_Snap.m_paPlayerInfos[i]->m_Team == Teams[Team]) m_Snap.m_paInfoByTeam[Index++] = m_Snap.m_paPlayerInfos[i]; } } CTuningParams StandardTuning; CServerInfo CurrentServerInfo; Client()->GetServerInfo(&CurrentServerInfo); if(CurrentServerInfo.m_aGameType[0] != '0') { if(str_comp(CurrentServerInfo.m_aGameType, "DM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "TDM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "CTF") != 0) m_ServerMode = SERVERMODE_MOD; else if(mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) == 0) m_ServerMode = SERVERMODE_PURE; else m_ServerMode = SERVERMODE_PUREMOD; } // add tuning to demo if(DemoRecorder()->IsRecording() && mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) != 0) { CMsgPacker Msg(NETMSGTYPE_SV_TUNEPARAMS); int *pParams = (int *)&m_Tuning; for(unsigned i = 0; i < sizeof(m_Tuning)/sizeof(int); i++) Msg.AddInt(pParams[i]); Client()->SendMsg(&Msg, MSGFLAG_RECORD|MSGFLAG_NOSEND); } if(!m_DDRaceMsgSent && m_Snap.m_pLocalInfo) { CNetMsg_Cl_IsDDRace Msg; Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); m_DDRaceMsgSent = true; } if(m_ShowOthers == -1 || (m_ShowOthers != -1 && m_ShowOthers != g_Config.m_ClShowOthers)) { // no need to send, default settings //if(!(m_ShowOthers == -1 && g_Config.m_ClShowOthers)) { CNetMsg_Cl_ShowOthers Msg; Msg.m_Show = g_Config.m_ClShowOthers; Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } // update state m_ShowOthers = g_Config.m_ClShowOthers; } }
void CGameClient::OnNewSnapshot() { m_NewTick = true; // clear out the invalid pointers mem_zero(&g_GameClient.m_Snap, sizeof(g_GameClient.m_Snap)); m_Snap.m_LocalCid = -1; // secure snapshot { int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int Index = 0; Index < Num; Index++) { IClient::CSnapItem Item; void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, Index, &Item); if(m_NetObjHandler.ValidateObj(Item.m_Type, pData, Item.m_DataSize) != 0) { if(g_Config.m_Debug) dbg_msg("game", "invalidated index=%d type=%d (%s) size=%d id=%d", Index, Item.m_Type, m_NetObjHandler.GetObjName(Item.m_Type), Item.m_DataSize, Item.m_Id); Client()->SnapInvalidateItem(IClient::SNAP_CURRENT, Index); } } } ProcessEvents(); if(g_Config.m_DbgStress) { if((Client()->GameTick()%100) == 0) { char aMessage[64]; int MsgLen = rand()%(sizeof(aMessage)-1); for(int i = 0; i < MsgLen; i++) aMessage[i] = 'a'+(rand()%('z'-'a')); aMessage[MsgLen] = 0; CNetMsg_Cl_Say Msg; Msg.m_Team = rand()&1; Msg.m_pMessage = aMessage; Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } } // go trough all the items in the snapshot and gather the info we want { m_Snap.m_aTeamSize[0] = m_Snap.m_aTeamSize[1] = 0; int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int i = 0; i < Num; i++) { IClient::CSnapItem Item; const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); if(Item.m_Type == NETOBJTYPE_CLIENTINFO) { const CNetObj_ClientInfo *pInfo = (const CNetObj_ClientInfo *)pData; int Cid = Item.m_Id; IntsToStr(&pInfo->m_Name0, 6, m_aClients[Cid].m_aName); IntsToStr(&pInfo->m_Skin0, 6, m_aClients[Cid].m_aSkinName); m_aClients[Cid].m_UseCustomColor = pInfo->m_UseCustomColor; m_aClients[Cid].m_ColorBody = pInfo->m_ColorBody; m_aClients[Cid].m_ColorFeet = pInfo->m_ColorFeet; // prepare the info if(m_aClients[Cid].m_aSkinName[0] == 'x' || m_aClients[Cid].m_aSkinName[1] == '_') str_copy(m_aClients[Cid].m_aSkinName, "default", 64); m_aClients[Cid].m_SkinInfo.m_ColorBody = m_pSkins->GetColor(m_aClients[Cid].m_ColorBody); m_aClients[Cid].m_SkinInfo.m_ColorFeet = m_pSkins->GetColor(m_aClients[Cid].m_ColorFeet); m_aClients[Cid].m_SkinInfo.m_Size = 64; // find new skin m_aClients[Cid].m_SkinId = g_GameClient.m_pSkins->Find(m_aClients[Cid].m_aSkinName); if(m_aClients[Cid].m_SkinId < 0) { m_aClients[Cid].m_SkinId = g_GameClient.m_pSkins->Find("default"); if(m_aClients[Cid].m_SkinId < 0) m_aClients[Cid].m_SkinId = 0; } if(m_aClients[Cid].m_UseCustomColor) m_aClients[Cid].m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(m_aClients[Cid].m_SkinId)->m_ColorTexture; else { m_aClients[Cid].m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(m_aClients[Cid].m_SkinId)->m_OrgTexture; m_aClients[Cid].m_SkinInfo.m_ColorBody = vec4(1,1,1,1); m_aClients[Cid].m_SkinInfo.m_ColorFeet = vec4(1,1,1,1); } m_aClients[Cid].UpdateRenderInfo(); g_GameClient.m_Snap.m_NumPlayers++; } else if(Item.m_Type == NETOBJTYPE_PLAYERINFO) { const CNetObj_PlayerInfo *pInfo = (const CNetObj_PlayerInfo *)pData; m_aClients[pInfo->m_ClientId].m_Team = pInfo->m_Team; m_Snap.m_paPlayerInfos[pInfo->m_ClientId] = pInfo; if(pInfo->m_Local) { m_Snap.m_LocalCid = Item.m_Id; m_Snap.m_pLocalInfo = pInfo; if (pInfo->m_Team == -1) m_Snap.m_Spectate = true; } // calculate team-balance if(pInfo->m_Team != -1) m_Snap.m_aTeamSize[pInfo->m_Team]++; } else if(Item.m_Type == NETOBJTYPE_CHARACTER) { const void *pOld = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_CHARACTER, Item.m_Id); if(pOld) { m_Snap.m_aCharacters[Item.m_Id].m_Active = true; m_Snap.m_aCharacters[Item.m_Id].m_Prev = *((const CNetObj_Character *)pOld); m_Snap.m_aCharacters[Item.m_Id].m_Cur = *((const CNetObj_Character *)pData); if(m_Snap.m_aCharacters[Item.m_Id].m_Prev.m_Tick) Evolve(&m_Snap.m_aCharacters[Item.m_Id].m_Prev, Client()->PrevGameTick()); if(m_Snap.m_aCharacters[Item.m_Id].m_Cur.m_Tick) Evolve(&m_Snap.m_aCharacters[Item.m_Id].m_Cur, Client()->GameTick()); } } else if(Item.m_Type == NETOBJTYPE_GAME) m_Snap.m_pGameobj = (CNetObj_Game *)pData; else if(Item.m_Type == NETOBJTYPE_FLAG) m_Snap.m_paFlags[Item.m_Id%2] = (const CNetObj_Flag *)pData; } } // setup local pointers if(m_Snap.m_LocalCid >= 0) { CSnapState::CCharacterInfo *c = &m_Snap.m_aCharacters[m_Snap.m_LocalCid]; if(c->m_Active) { m_Snap.m_pLocalCharacter = &c->m_Cur; m_Snap.m_pLocalPrevCharacter = &c->m_Prev; m_LocalCharacterPos = vec2(m_Snap.m_pLocalCharacter->m_X, m_Snap.m_pLocalCharacter->m_Y); } } else m_Snap.m_Spectate = true; CTuningParams StandardTuning; CServerInfo CurrentServerInfo; Client()->GetServerInfo(&CurrentServerInfo); if(CurrentServerInfo.m_aGameType[0] != '0') { if(str_comp(CurrentServerInfo.m_aGameType, "DM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "TDM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "CTF") != 0) m_ServerMode = SERVERMODE_MOD; else if(mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) == 0) m_ServerMode = SERVERMODE_PURE; else m_ServerMode = SERVERMODE_PUREMOD; } // update render info for(int i = 0; i < MAX_CLIENTS; i++) m_aClients[i].UpdateRenderInfo(); }
int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int StorageType) { CDataFileReader DataFile; //DATAFILE *df = datafile_load(filename); if(!DataFile.Open(pStorage, pFileName, StorageType)) return 0; Clean(); // check version CMapItemVersion *pItem = (CMapItemVersion *)DataFile.FindItem(MAPITEMTYPE_VERSION, 0); if(!pItem) { // import old map /*MAP old_mapstuff; editor->reset(); editor_load_old(df, this); */ } else if(pItem->m_Version == 1) { //editor.reset(false); // load images { int Start, Num; DataFile.GetType( MAPITEMTYPE_IMAGE, &Start, &Num); for(int i = 0; i < Num; i++) { CMapItemImage *pItem = (CMapItemImage *)DataFile.GetItem(Start+i, 0, 0); char *pName = (char *)DataFile.GetData(pItem->m_ImageName); // copy base info CEditorImage *pImg = new CEditorImage(m_pEditor); pImg->m_External = pItem->m_External; if(pItem->m_External) { char aBuf[256]; str_format(aBuf, sizeof(aBuf),"mapres/%s.png", pName); // load external CEditorImage ImgInfo(m_pEditor); if(m_pEditor->Graphics()->LoadPNG(&ImgInfo, aBuf, IStorage::TYPE_ALL)) { *pImg = ImgInfo; pImg->m_TexID = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0); pImg->m_External = 1; } } else { pImg->m_Width = pItem->m_Width; pImg->m_Height = pItem->m_Height; pImg->m_Format = CImageInfo::FORMAT_RGBA; // copy image data void *pData = DataFile.GetData(pItem->m_ImageData); pImg->m_pData = mem_alloc(pImg->m_Width*pImg->m_Height*4, 1); mem_copy(pImg->m_pData, pData, pImg->m_Width*pImg->m_Height*4); pImg->m_TexID = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, CImageInfo::FORMAT_AUTO, 0); } // copy image name if(pName) str_copy(pImg->m_aName, pName, 128); m_lImages.add(pImg); // unload image DataFile.UnloadData(pItem->m_ImageData); DataFile.UnloadData(pItem->m_ImageName); } } // load groups { int LayersStart, LayersNum; DataFile.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum); int Start, Num; DataFile.GetType(MAPITEMTYPE_GROUP, &Start, &Num); for(int g = 0; g < Num; g++) { CMapItemGroup *pGItem = (CMapItemGroup *)DataFile.GetItem(Start+g, 0, 0); if(pGItem->m_Version < 1 || pGItem->m_Version > CMapItemGroup::CURRENT_VERSION) continue; CLayerGroup *pGroup = NewGroup(); pGroup->m_ParallaxX = pGItem->m_ParallaxX; pGroup->m_ParallaxY = pGItem->m_ParallaxY; pGroup->m_OffsetX = pGItem->m_OffsetX; pGroup->m_OffsetY = pGItem->m_OffsetY; if(pGItem->m_Version >= 2) { pGroup->m_UseClipping = pGItem->m_UseClipping; pGroup->m_ClipX = pGItem->m_ClipX; pGroup->m_ClipY = pGItem->m_ClipY; pGroup->m_ClipW = pGItem->m_ClipW; pGroup->m_ClipH = pGItem->m_ClipH; } for(int l = 0; l < pGItem->m_NumLayers; l++) { CLayer *pLayer = 0; CMapItemLayer *pLayerItem = (CMapItemLayer *)DataFile.GetItem(LayersStart+pGItem->m_StartLayer+l, 0, 0); if(!pLayerItem) continue; if(pLayerItem->m_Type == LAYERTYPE_TILES) { CMapItemLayerTilemap *pTilemapItem = (CMapItemLayerTilemap *)pLayerItem; CLayerTiles *pTiles = 0; if(pTilemapItem->m_Flags&1) { pTiles = new CLayerGame(pTilemapItem->m_Width, pTilemapItem->m_Height); MakeGameLayer(pTiles); MakeGameGroup(pGroup); } else { pTiles = new CLayerTiles(pTilemapItem->m_Width, pTilemapItem->m_Height); pTiles->m_pEditor = m_pEditor; pTiles->m_Color.r = pTilemapItem->m_Color.r; pTiles->m_Color.g = pTilemapItem->m_Color.g; pTiles->m_Color.b = pTilemapItem->m_Color.b; pTiles->m_Color.a = pTilemapItem->m_Color.a; } pLayer = pTiles; pGroup->AddLayer(pTiles); void *pData = DataFile.GetData(pTilemapItem->m_Data); pTiles->m_Image = pTilemapItem->m_Image; pTiles->m_Game = pTilemapItem->m_Flags&1; mem_copy(pTiles->m_pTiles, pData, pTiles->m_Width*pTiles->m_Height*sizeof(CTile)); if(pTiles->m_Game && pTilemapItem->m_Version == MakeVersion(1, *pTilemapItem)) { for(int i = 0; i < pTiles->m_Width*pTiles->m_Height; i++) { if(pTiles->m_pTiles[i].m_Index) pTiles->m_pTiles[i].m_Index += ENTITY_OFFSET; } } DataFile.UnloadData(pTilemapItem->m_Data); } else if(pLayerItem->m_Type == LAYERTYPE_QUADS) { CMapItemLayerQuads *pQuadsItem = (CMapItemLayerQuads *)pLayerItem; CLayerQuads *pQuads = new CLayerQuads; pQuads->m_pEditor = m_pEditor; pLayer = pQuads; pQuads->m_Image = pQuadsItem->m_Image; if(pQuads->m_Image < -1 || pQuads->m_Image >= m_lImages.size()) pQuads->m_Image = -1; void *pData = DataFile.GetDataSwapped(pQuadsItem->m_Data); pGroup->AddLayer(pQuads); pQuads->m_lQuads.set_size(pQuadsItem->m_NumQuads); mem_copy(pQuads->m_lQuads.base_ptr(), pData, sizeof(CQuad)*pQuadsItem->m_NumQuads); DataFile.UnloadData(pQuadsItem->m_Data); } if(pLayer) pLayer->m_Flags = pLayerItem->m_Flags; } } } // load envelopes { CEnvPoint *pPoints = 0; { int Start, Num; DataFile.GetType(MAPITEMTYPE_ENVPOINTS, &Start, &Num); if(Num) pPoints = (CEnvPoint *)DataFile.GetItem(Start, 0, 0); } int Start, Num; DataFile.GetType(MAPITEMTYPE_ENVELOPE, &Start, &Num); for(int e = 0; e < Num; e++) { CMapItemEnvelope *pItem = (CMapItemEnvelope *)DataFile.GetItem(Start+e, 0, 0); CEnvelope *pEnv = new CEnvelope(pItem->m_Channels); pEnv->m_lPoints.set_size(pItem->m_NumPoints); mem_copy(pEnv->m_lPoints.base_ptr(), &pPoints[pItem->m_StartPoint], sizeof(CEnvPoint)*pItem->m_NumPoints); if(pItem->m_aName[0] != -1) // compatibility with old maps IntsToStr(pItem->m_aName, sizeof(pItem->m_aName)/sizeof(int), pEnv->m_aName); m_lEnvelopes.add(pEnv); } } } return 1; }
void CGameClient::OnNewSnapshot() { // clear out the invalid pointers mem_zero(&m_Snap, sizeof(m_Snap)); // secure snapshot { int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int Index = 0; Index < Num; Index++) { IClient::CSnapItem Item; const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, Index, &Item); if(m_NetObjHandler.ValidateObj(Item.m_Type, pData, Item.m_DataSize) != 0) { if(g_Config.m_Debug) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "invalidated index=%d type=%d (%s) size=%d id=%d", Index, Item.m_Type, m_NetObjHandler.GetObjName(Item.m_Type), Item.m_DataSize, Item.m_ID); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); } Client()->SnapInvalidateItem(IClient::SNAP_CURRENT, Index); } } } ProcessEvents(); if(g_Config.m_DbgStress) { if((Client()->GameTick()%100) == 0) { char aMessage[64]; int MsgLen = random_int()%(sizeof(aMessage)-1); for(int i = 0; i < MsgLen; i++) aMessage[i] = 'a'+(random_int()%('z'-'a')); aMessage[MsgLen] = 0; CNetMsg_Cl_Say Msg; Msg.m_Mode = random_int()&1; Msg.m_Target = -1; Msg.m_pMessage = aMessage; Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } } CTuningParams StandardTuning; if(Client()->State() == IClient::STATE_DEMOPLAYBACK) { m_Tuning = StandardTuning; mem_zero(&m_GameInfo, sizeof(m_GameInfo)); } // go trough all the items in the snapshot and gather the info we want { int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int i = 0; i < Num; i++) { IClient::CSnapItem Item; const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); // demo items if(Client()->State() == IClient::STATE_DEMOPLAYBACK) { if(Item.m_Type == NETOBJTYPE_DE_CLIENTINFO) { const CNetObj_De_ClientInfo *pInfo = (const CNetObj_De_ClientInfo *)pData; int ClientID = Item.m_ID; CClientData *pClient = &m_aClients[ClientID]; if(pInfo->m_Local) m_LocalClientID = ClientID; pClient->m_Active = true; pClient->m_Team = pInfo->m_Team; IntsToStr(pInfo->m_aName, 4, pClient->m_aName); IntsToStr(pInfo->m_aClan, 3, pClient->m_aClan); pClient->m_Country = pInfo->m_Country; for(int p = 0; p < NUM_SKINPARTS; p++) { IntsToStr(pInfo->m_aaSkinPartNames[p], 6, pClient->m_aaSkinPartNames[p]); pClient->m_aUseCustomColors[p] = pInfo->m_aUseCustomColors[p]; pClient->m_aSkinPartColors[p] = pInfo->m_aSkinPartColors[p]; } m_GameInfo.m_NumPlayers++; // calculate team-balance if(pClient->m_Team != TEAM_SPECTATORS) m_GameInfo.m_aTeamSize[pClient->m_Team]++; } else if(Item.m_Type == NETOBJTYPE_DE_GAMEINFO) { const CNetObj_De_GameInfo *pInfo = (const CNetObj_De_GameInfo *)pData; m_GameInfo.m_GameFlags = pInfo->m_GameFlags; m_GameInfo.m_ScoreLimit = pInfo->m_ScoreLimit; m_GameInfo.m_TimeLimit = pInfo->m_TimeLimit; m_GameInfo.m_MatchNum = pInfo->m_MatchNum; m_GameInfo.m_MatchCurrent = pInfo->m_MatchCurrent; } else if(Item.m_Type == NETOBJTYPE_DE_TUNEPARAMS) { const CNetObj_De_TuneParams *pInfo = (const CNetObj_De_TuneParams *)pData; mem_copy(&m_Tuning, pInfo->m_aTuneParams, sizeof(m_Tuning)); m_ServerMode = SERVERMODE_PURE; } } // network items if(Item.m_Type == NETOBJTYPE_PLAYERINFO) { const CNetObj_PlayerInfo *pInfo = (const CNetObj_PlayerInfo *)pData; int ClientID = Item.m_ID; if(m_aClients[ClientID].m_Active) { m_Snap.m_paPlayerInfos[ClientID] = pInfo; m_Snap.m_aInfoByScore[ClientID].m_pPlayerInfo = pInfo; m_Snap.m_aInfoByScore[ClientID].m_ClientID = ClientID; if(m_LocalClientID == ClientID) { m_Snap.m_pLocalInfo = pInfo; if(m_aClients[ClientID].m_Team == TEAM_SPECTATORS) { m_Snap.m_SpecInfo.m_Active = true; m_Snap.m_SpecInfo.m_SpecMode = SPEC_FREEVIEW; m_Snap.m_SpecInfo.m_SpectatorID = -1; } } } } else if(Item.m_Type == NETOBJTYPE_CHARACTER) { const void *pOld = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_CHARACTER, Item.m_ID); m_Snap.m_aCharacters[Item.m_ID].m_Cur = *((const CNetObj_Character *)pData); // clamp ammo count for non ninja weapon if(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_Weapon != WEAPON_NINJA) m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_AmmoCount = clamp(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_AmmoCount, 0, 10); if(pOld) { m_Snap.m_aCharacters[Item.m_ID].m_Active = true; m_Snap.m_aCharacters[Item.m_ID].m_Prev = *((const CNetObj_Character *)pOld); if(m_Snap.m_aCharacters[Item.m_ID].m_Prev.m_Tick) EvolveCharacter(&m_Snap.m_aCharacters[Item.m_ID].m_Prev, Client()->PrevGameTick()); if(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_Tick) EvolveCharacter(&m_Snap.m_aCharacters[Item.m_ID].m_Cur, Client()->GameTick()); } if(Item.m_ID != m_LocalClientID || Client()->State() == IClient::STATE_DEMOPLAYBACK) ProcessTriggeredEvents(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_TriggeredEvents, vec2(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_X, m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_Y)); } else if(Item.m_Type == NETOBJTYPE_SPECTATORINFO) { m_Snap.m_pSpectatorInfo = (const CNetObj_SpectatorInfo *)pData; m_Snap.m_pPrevSpectatorInfo = (const CNetObj_SpectatorInfo *)Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_SPECTATORINFO, Item.m_ID); m_Snap.m_SpecInfo.m_Active = true; m_Snap.m_SpecInfo.m_SpecMode = m_Snap.m_pSpectatorInfo->m_SpecMode; m_Snap.m_SpecInfo.m_SpectatorID = m_Snap.m_pSpectatorInfo->m_SpectatorID; } else if(Item.m_Type == NETOBJTYPE_GAMEDATA) { m_Snap.m_pGameData = (const CNetObj_GameData *)pData; static bool s_GameOver = 0; if(!s_GameOver && m_Snap.m_pGameData->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER) OnGameOver(); else if(s_GameOver && !(m_Snap.m_pGameData->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)) OnStartGame(); s_GameOver = m_Snap.m_pGameData->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER; } else if(Item.m_Type == NETOBJTYPE_GAMEDATATEAM) { m_Snap.m_pGameDataTeam = (const CNetObj_GameDataTeam *)pData; } else if(Item.m_Type == NETOBJTYPE_GAMEDATAFLAG) { m_Snap.m_pGameDataFlag = (const CNetObj_GameDataFlag *)pData; m_Snap.m_GameDataFlagSnapID = Item.m_ID; } else if(Item.m_Type == NETOBJTYPE_FLAG) m_Snap.m_paFlags[Item.m_ID%2] = (const CNetObj_Flag *)pData; } } // setup local pointers if(m_LocalClientID >= 0) { CSnapState::CCharacterInfo *c = &m_Snap.m_aCharacters[m_LocalClientID]; if(c->m_Active) { m_Snap.m_pLocalCharacter = &c->m_Cur; m_Snap.m_pLocalPrevCharacter = &c->m_Prev; m_LocalCharacterPos = vec2(m_Snap.m_pLocalCharacter->m_X, m_Snap.m_pLocalCharacter->m_Y); } else if(Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_CHARACTER, m_LocalClientID)) { // player died m_pControls->OnPlayerDeath(); } } else { m_Snap.m_SpecInfo.m_Active = true; if(Client()->State() == IClient::STATE_DEMOPLAYBACK && DemoPlayer()->GetDemoType() == IDemoPlayer::DEMOTYPE_SERVER && m_DemoSpecID != -1 && m_Snap.m_aCharacters[m_DemoSpecID].m_Active) { m_Snap.m_SpecInfo.m_SpecMode = SPEC_PLAYER; m_Snap.m_SpecInfo.m_SpectatorID = m_DemoSpecID; } else { if (m_DemoSpecMode == SPEC_PLAYER) { m_Snap.m_SpecInfo.m_SpecMode = SPEC_FREEVIEW; m_Snap.m_SpecInfo.m_SpectatorID = -1; } else { m_Snap.m_SpecInfo.m_SpecMode = m_DemoSpecMode; m_Snap.m_SpecInfo.m_SpectatorID = m_DemoSpecID; } } } // sort player infos by score for(int k = 0; k < MAX_CLIENTS-1; k++) // ffs, bubblesort { for(int i = 0; i < MAX_CLIENTS-k-1; i++) { if(m_Snap.m_aInfoByScore[i+1].m_pPlayerInfo && (!m_Snap.m_aInfoByScore[i].m_pPlayerInfo || m_Snap.m_aInfoByScore[i].m_pPlayerInfo->m_Score < m_Snap.m_aInfoByScore[i+1].m_pPlayerInfo->m_Score)) { CPlayerInfoItem Tmp = m_Snap.m_aInfoByScore[i]; m_Snap.m_aInfoByScore[i] = m_Snap.m_aInfoByScore[i+1]; m_Snap.m_aInfoByScore[i+1] = Tmp; } } } // calc some player stats for(int i = 0; i < MAX_CLIENTS; ++i) { if(!m_Snap.m_paPlayerInfos[i]) continue; // count not ready players if((m_Snap.m_pGameData->m_GameStateFlags&(GAMESTATEFLAG_STARTCOUNTDOWN|GAMESTATEFLAG_PAUSED|GAMESTATEFLAG_WARMUP)) && m_Snap.m_pGameData->m_GameStateEndTick == 0 && m_aClients[i].m_Team != TEAM_SPECTATORS && !(m_Snap.m_paPlayerInfos[i]->m_PlayerFlags&PLAYERFLAG_READY)) m_Snap.m_NotReadyCount++; // count alive players per team if((m_GameInfo.m_GameFlags&GAMEFLAG_SURVIVAL) && m_aClients[i].m_Team != TEAM_SPECTATORS && !(m_Snap.m_paPlayerInfos[i]->m_PlayerFlags&PLAYERFLAG_DEAD)) m_Snap.m_AliveCount[m_aClients[i].m_Team]++; } if(Client()->State() == IClient::STATE_DEMOPLAYBACK) { for(int i = 0; i < MAX_CLIENTS; ++i) { if(m_aClients[i].m_Active) m_aClients[i].UpdateRenderInfo(this, true); } } CServerInfo CurrentServerInfo; Client()->GetServerInfo(&CurrentServerInfo); if(str_comp(CurrentServerInfo.m_aGameType, "DM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "TDM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "CTF") != 0 && str_comp(CurrentServerInfo.m_aGameType, "LMS") != 0 && str_comp(CurrentServerInfo.m_aGameType, "SUR") != 0) m_ServerMode = SERVERMODE_MOD; else if(mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) == 0) m_ServerMode = SERVERMODE_PURE; else m_ServerMode = SERVERMODE_PUREMOD; }
void CMapReader::Generate(CGenInfo *pInfo) { m_OverallBenchmark.Unpause(); // create folders char aGeneratedFolder[256]; sprintf(aGeneratedFolder, "%sgenerated/%s", pInfo->m_aCurrentDir, pInfo->m_aMap); char aGeneratedMapresFolder[256]; sprintf(aGeneratedMapresFolder, "%s/mapres", aGeneratedFolder); MakeDir(aGeneratedFolder); MakeDir(aGeneratedMapresFolder); // check map version CMapItemVersion *pVersion = (CMapItemVersion *)m_Reader.FindItem(MAPITEMTYPE_VERSION, 0); if(!pVersion || pVersion->m_Version != 1) return; // create generating file char aGenerating[256]; sprintf(aGenerating, "%s/generating", aGeneratedFolder); FILE *pGeneratingFile = fopen(aGenerating, "wb"); if(pGeneratingFile) fclose(pGeneratingFile); // load images m_ImagesBenchmark.Unpause(); int ImagesStart; int ImagesNum; m_Reader.GetType(MAPITEMTYPE_IMAGE, &ImagesStart, &ImagesNum); CMapItemImage *pImages = NULL; if(ImagesNum > 0) { pImages = new CMapItemImage[ImagesNum]; for(int i = ImagesStart; i < ImagesStart+ImagesNum; i++) { CMapItemImage *pImage = (CMapItemImage *)m_Reader.GetItem(i, NULL, NULL); if(!pImage->m_External && pInfo->m_DumpEmbedded) { const char *pName = (char *)m_Reader.GetData(pImage->m_ImageName); unsigned char *pData = (unsigned char *)m_Reader.GetData(pImage->m_ImageData); char aImageFilename[512]; sprintf(aImageFilename, "%s/%s.png", aGeneratedMapresFolder, pName); CImageWrite Image; Image.Open(aImageFilename, pImage->m_Width, pImage->m_Height); Image.SetPixels(pData); Image.Save(); } pImages[i-ImagesStart] = *pImage; } } m_ImagesBenchmark.Pause(); // load groups and layers int GroupsStart; int GroupsNum; m_Reader.GetType(MAPITEMTYPE_GROUP, &GroupsStart, &GroupsNum); int LayersStart; int LayersNum; m_Reader.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum); for(int g = GroupsStart; g < GroupsStart+GroupsNum; g++) { CMapItemGroup *pGroup = (CMapItemGroup *)m_Reader.GetItem(g, NULL, NULL); if(pGroup->m_Version < 1 || pGroup->m_Version > 2) continue; for(int l = LayersStart + pGroup->m_StartLayer; l < LayersStart + pGroup->m_StartLayer+pGroup->m_NumLayers; l++) { if(l >= LayersStart+LayersNum) break; CMapItemLayer *pLayer = (CMapItemLayer *)m_Reader.GetItem(l, NULL, NULL); if(pLayer->m_Type == LAYERTYPE_TILES) { m_TilemapsBenchmark.Unpause(); CMapItemLayerTilemap *pTilesLayer = (CMapItemLayerTilemap *)pLayer; bool GameLayer = (pTilesLayer->m_Flags & TILESLAYERFLAG_GAME) ? true : false; if((GameLayer && !pInfo->m_DumpGameTilemap) || (!GameLayer && !pInfo->m_DumpTilemaps)) continue; if(!GameLayer && pTilesLayer->m_Image < 0) continue; CMapItemImage *pImage = NULL; if(!GameLayer) pImage = &pImages[pTilesLayer->m_Image]; const char *pTilesetName; if(GameLayer) pTilesetName = pInfo->m_aEntities; else pTilesetName = (char *)m_Reader.GetData(pImage->m_ImageName); CTileset Src; if(GameLayer || pImage->m_External) { char aTilesetFilename[512]; sprintf(aTilesetFilename, "%smapres/%s.png", pInfo->m_aCurrentDir, pTilesetName); bool Success = Src.Open(aTilesetFilename); if(!Success) continue; } else { bool Success = Src.OpenFromBuffer((unsigned char *)m_Reader.GetData(pImage->m_ImageData), pImage->m_Width, pImage->m_Height); if(!Success) continue; } char aTilemapFilename[512]; if(GameLayer) sprintf(aTilemapFilename, "%s/tiles_game_%d.png", aGeneratedFolder, pTilesLayer->m_Data); else sprintf(aTilemapFilename, "%s/tiles_%d.png", aGeneratedFolder, pTilesLayer->m_Data); CTilemap Dest; bool Success = Dest.Open(aTilemapFilename, pTilesLayer->m_Width, pTilesLayer->m_Height, &Src, pInfo->m_TileSize); if(!Success) continue; CTile *pTilesData = (CTile *)m_Reader.GetData(pTilesLayer->m_Data); for(int x = 0; x < pTilesLayer->m_Width; x++) { for(int y = 0; y < pTilesLayer->m_Height; y++) { CTile *pTile = &pTilesData[y*pTilesLayer->m_Width + x]; if(pTile->m_Index == 0) continue; Dest.SetTile(x, y, pTile->m_Index, pTile->m_Flags); } } Dest.Colorize(&pTilesLayer->m_Color); Dest.Save(); Src.Close(); m_TilemapsBenchmark.Pause(); } else if(pLayer->m_Type == LAYERTYPE_QUADS) { m_QuadsBenchmark.Unpause(); CMapItemLayerQuads *pQuadsLayer = (CMapItemLayerQuads *)pLayer; if(!pInfo->m_DumpQuads) continue; CImageRead Src; CMapItemImage *pImage = NULL; if(pQuadsLayer->m_Image >= 0) pImage = &pImages[pQuadsLayer->m_Image]; if(pQuadsLayer->m_Image >= 0) { const char *pImageName = (char *)m_Reader.GetData(pImage->m_ImageName); if(pImage->m_External) { char aImageFilename[512]; sprintf(aImageFilename, "%smapres/%s.png", pInfo->m_aCurrentDir, pImageName); bool Success = Src.Open(aImageFilename); if(!Success) continue; } else { bool Success = Src.OpenFromBuffer((unsigned char *)m_Reader.GetData(pImage->m_ImageData), pImage->m_Width, pImage->m_Height); if(!Success) continue; } } CQuad *pQuadsData = (CQuad *)m_Reader.GetData(pQuadsLayer->m_Data); for(int q = 0; q < pQuadsLayer->m_NumQuads; q++) { CQuad *pQuad = &pQuadsData[q]; int MinX = min(min(min(pQuad->m_aPoints[0].x, pQuad->m_aPoints[1].x), pQuad->m_aPoints[2].x), pQuad->m_aPoints[3].x) / 1024; int MinY = min(min(min(pQuad->m_aPoints[0].y, pQuad->m_aPoints[1].y), pQuad->m_aPoints[2].y), pQuad->m_aPoints[3].y) / 1024; int MaxX = max(max(max(pQuad->m_aPoints[0].x, pQuad->m_aPoints[1].x), pQuad->m_aPoints[2].x), pQuad->m_aPoints[3].x) / 1024; int MaxY = max(max(max(pQuad->m_aPoints[0].y, pQuad->m_aPoints[1].y), pQuad->m_aPoints[2].y), pQuad->m_aPoints[3].y) / 1024; int Width = MaxX-MinX; int Height = MaxY-MinY; if(Width <= 0 || Height <= 0) continue; char aQuadsFilename[512]; sprintf(aQuadsFilename, "%s/quads_%d_%d.png", aGeneratedFolder, pQuadsLayer->m_Data, q); CQuads Dest; bool Success = Dest.Open(aQuadsFilename, Width, Height, pInfo->m_TileSize); if(!Success) continue; if(pQuadsLayer->m_Image < 0) Dest.FillWhite(); else Dest.DrawImage(&Src); Dest.DrawGradient(pQuad->m_aColors); Dest.Save(); } m_QuadsBenchmark.Pause(); } } } // dump metadata if(pInfo->m_DumpMetadata) { m_MetadataBenchmark.Unpause(); CXMLDocument Doc; CXMLItem *pMainItem = Doc.Open("map"); pMainItem->AddAttributeInt("version", pVersion->m_Version); for(int i = 0; i < ImagesNum; i++) { const char *pName = (char *)m_Reader.GetData(pImages[i].m_ImageName); CXMLItem *pImageItem = pMainItem->AddChild("image"); pImageItem->AddAttributeInt("version", pImages[i].m_Version); pImageItem->AddAttributeInt("width", pImages[i].m_Width); pImageItem->AddAttributeInt("height", pImages[i].m_Height); pImageItem->AddAttributeBool("external", pImages[i].m_External); pImageItem->AddAttributeStr("name", pName); } for(int g = GroupsStart; g < GroupsStart+GroupsNum; g++) { CMapItemGroup *pGroup = (CMapItemGroup *)m_Reader.GetItem(g, NULL, NULL); CXMLItem *pGroupItem = pMainItem->AddChild("group"); pGroupItem->AddAttributeInt("version", pGroup->m_Version); pGroupItem->AddAttributeInt("offset_x", pGroup->m_OffsetX); pGroupItem->AddAttributeInt("offset_y", pGroup->m_OffsetY); pGroupItem->AddAttributeInt("parallax_x", pGroup->m_ParallaxX); pGroupItem->AddAttributeInt("parallax_y", pGroup->m_ParallaxY); if(pGroup->m_Version >= 2) { pGroupItem->AddAttributeBool("use_clipping", pGroup->m_UseClipping); pGroupItem->AddAttributeInt("clip_x", pGroup->m_ClipX); pGroupItem->AddAttributeInt("clip_y", pGroup->m_ClipY); pGroupItem->AddAttributeInt("clip_w", pGroup->m_ClipW); pGroupItem->AddAttributeInt("clip_h", pGroup->m_ClipH); } for(int l = LayersStart + pGroup->m_StartLayer; l < LayersStart + pGroup->m_StartLayer+pGroup->m_NumLayers; l++) { if(l >= LayersStart+LayersNum) break; CMapItemLayer *pLayer = (CMapItemLayer *)m_Reader.GetItem(l, NULL, NULL); CXMLItem *pLayerItem = pGroupItem->AddChild("layer"); if(pLayer->m_Type == LAYERTYPE_TILES) pLayerItem->AddAttributeStr("type", "tiles"); else if(pLayer->m_Type == LAYERTYPE_QUADS) pLayerItem->AddAttributeStr("type", "quads"); else pLayerItem->AddAttributeStr("type", "invalid"); pLayerItem->AddAttributeBool("detail", pLayer->m_Flags&TILESLAYERFLAG_GAME); if(pLayer->m_Type == LAYERTYPE_TILES) { CMapItemLayerTilemap *pTilesLayer = (CMapItemLayerTilemap *)pLayer; const char *pImageName = ""; if(pTilesLayer->m_Image >= 0 && pTilesLayer->m_Image < ImagesNum) pImageName = (char *)m_Reader.GetData(pImages[pTilesLayer->m_Image].m_ImageName); pLayerItem->AddAttributeInt("version", pTilesLayer->m_Version); pLayerItem->AddAttributeInt("width", pTilesLayer->m_Width); pLayerItem->AddAttributeInt("height", pTilesLayer->m_Height); pLayerItem->AddAttributeBool("game", pTilesLayer->m_Flags&TILESLAYERFLAG_GAME); pLayerItem->AddAttributeInt("color_env", pTilesLayer->m_ColorEnv); pLayerItem->AddAttributeInt("color_env_offset", pTilesLayer->m_ColorEnvOffset); pLayerItem->AddAttributeStr("image", pImageName); pLayerItem->AddAttributeInt("data", pTilesLayer->m_Data); CXMLItem *pColorItem = pLayerItem->AddChild("color"); pColorItem->AddAttributeInt("r", pTilesLayer->m_Color.r); pColorItem->AddAttributeInt("g", pTilesLayer->m_Color.g); pColorItem->AddAttributeInt("b", pTilesLayer->m_Color.b); pColorItem->AddAttributeInt("a", pTilesLayer->m_Color.a); } else if(pLayer->m_Type == LAYERTYPE_QUADS) { CMapItemLayerQuads *pQuadsLayer = (CMapItemLayerQuads *)pLayer; const char *pImageName = ""; if(pQuadsLayer->m_Image >= 0 && pQuadsLayer->m_Image < ImagesNum) pImageName = (char *)m_Reader.GetData(pImages[pQuadsLayer->m_Image].m_ImageName); pLayerItem->AddAttributeInt("version", pQuadsLayer->m_Version); pLayerItem->AddAttributeStr("image", pImageName); pLayerItem->AddAttributeInt("data", pQuadsLayer->m_Data); CQuad *pQuadsData = (CQuad *)m_Reader.GetData(pQuadsLayer->m_Data); for(int q = 0; q < pQuadsLayer->m_NumQuads; q++) { CQuad *pQuad = &pQuadsData[q]; CXMLItem *pQuadItem = pLayerItem->AddChild("quad"); pQuadItem->AddAttributeInt("pos_env", pQuad->m_PosEnv); pQuadItem->AddAttributeInt("pos_env_offset", pQuad->m_PosEnvOffset); pQuadItem->AddAttributeInt("color_env", pQuad->m_ColorEnv); pQuadItem->AddAttributeInt("color_env_offset", pQuad->m_ColorEnvOffset); pQuadItem->AddAttributeInt("data", q); for(int k = 0; k < 5; k++) { CXMLItem *pPointItem = pQuadItem->AddChild("point"); pPointItem->AddAttributeInt("x", fx2f(pQuad->m_aPoints[k].x)); pPointItem->AddAttributeInt("y", fx2f(pQuad->m_aPoints[k].y)); } for(int k = 0; k < 4; k++) { CXMLItem *pColorItem = pQuadItem->AddChild("color"); pColorItem->AddAttributeInt("r", pQuad->m_aColors[k].r); pColorItem->AddAttributeInt("g", pQuad->m_aColors[k].g); pColorItem->AddAttributeInt("b", pQuad->m_aColors[k].b); pColorItem->AddAttributeInt("a", pQuad->m_aColors[k].a); } for(int k = 0; k < 4; k++) { CXMLItem *pTexcoordItem = pQuadItem->AddChild("texcoord"); pTexcoordItem->AddAttributeInt("x", fx2f(pQuad->m_aTexcoords[k].x)); pTexcoordItem->AddAttributeInt("y", fx2f(pQuad->m_aTexcoords[k].y)); } } } } } int EnvPointsStart; int EnvPointsNum; m_Reader.GetType(MAPITEMTYPE_ENVPOINTS, &EnvPointsStart, &EnvPointsNum); CEnvPoint *pPoints = 0; if(EnvPointsNum) pPoints = (CEnvPoint *)m_Reader.GetItem(EnvPointsStart, NULL, NULL); int EnvStart; int EnvNum; m_Reader.GetType(MAPITEMTYPE_ENVELOPE, &EnvStart, &EnvNum); for(int e = EnvStart; e < EnvStart+EnvNum; e++) { CMapItemEnvelope *pEnv = (CMapItemEnvelope *)m_Reader.GetItem(e, NULL, NULL); CXMLItem *pEnvItem = pMainItem->AddChild("envelope"); pEnvItem->AddAttributeInt("version", pEnv->m_Version); if(pEnv->m_Channels == 3) pEnvItem->AddAttributeStr("type", "pos"); else if(pEnv->m_Channels == 4) pEnvItem->AddAttributeStr("type", "color"); else pEnvItem->AddAttributeStr("type", "invalid"); if(pEnv->m_aName[0] != -1) { char aEnvName[64]; IntsToStr(pEnv->m_aName, sizeof(pEnv->m_aName)/sizeof(int), aEnvName); pEnvItem->AddAttributeStr("name", aEnvName); } for(int p = pEnv->m_StartPoint; p < pEnv->m_StartPoint+pEnv->m_NumPoints; p++) { CXMLItem *pEnvPointItem = pEnvItem->AddChild("envpoint"); pEnvPointItem->AddAttributeInt("time", pPoints[p].m_Time); if(p != pEnv->m_StartPoint+pEnv->m_NumPoints -1) { if(pPoints[p].m_Curvetype == CURVETYPE_STEP) pEnvPointItem->AddAttributeStr("curvetype", "step"); else if(pPoints[p].m_Curvetype == CURVETYPE_LINEAR) pEnvPointItem->AddAttributeStr("curvetype", "linear"); else if(pPoints[p].m_Curvetype == CURVETYPE_SLOW) pEnvPointItem->AddAttributeStr("curvetype", "slow"); else if(pPoints[p].m_Curvetype == CURVETYPE_FAST) pEnvPointItem->AddAttributeStr("curvetype", "fast"); else if(pPoints[p].m_Curvetype == CURVETYPE_SMOOTH) pEnvPointItem->AddAttributeStr("curvetype", "smooth"); else pEnvPointItem->AddAttributeStr("curvetype", "invalid"); } if(pEnv->m_Channels == 3) { pEnvPointItem->AddAttributeInt("x", fx2f(pPoints[p].m_aValues[0])); pEnvPointItem->AddAttributeInt("y", fx2f(pPoints[p].m_aValues[1])); pEnvPointItem->AddAttributeInt("r", fx2f(pPoints[p].m_aValues[2])); } else if(pEnv->m_Channels == 4) { pEnvPointItem->AddAttributeInt("r", fx2f(pPoints[p].m_aValues[0])*255); pEnvPointItem->AddAttributeInt("g", fx2f(pPoints[p].m_aValues[1])*255); pEnvPointItem->AddAttributeInt("b", fx2f(pPoints[p].m_aValues[2])*255); pEnvPointItem->AddAttributeInt("a", fx2f(pPoints[p].m_aValues[3])*255); } } } char aMetadataFilename[512]; sprintf(aMetadataFilename, "%s/metadata.xml", aGeneratedFolder); Doc.Save(aMetadataFilename); Doc.Close(); m_MetadataBenchmark.Pause(); } if(ImagesNum > 0) delete pImages; remove(aGenerating); m_OverallBenchmark.Pause(); if(pInfo->m_ShowBenchmark) { printf("Benchmark results:\n"); printf(" Images dumping:\t%dms\n", m_ImagesBenchmark.GetTime()); printf(" Tilemaps dumping:\t%dms\n", m_TilemapsBenchmark.GetTime()); printf(" Quads dumping:\t%dms\n", m_QuadsBenchmark.GetTime()); printf(" Metadata dumping:\t%dms\n", m_MetadataBenchmark.GetTime()); printf(" Overall:\t\t%dms\n", m_OverallBenchmark.GetTime()); } }