1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
3 | #include "eventhandler.h" |
4 | |
5 | #include "entity.h" |
6 | #include "gamecontext.h" |
7 | |
8 | #include <base/system.h> |
9 | #include <base/vmath.h> |
10 | |
11 | ////////////////////////////////////////////////// |
12 | // Event handler |
13 | ////////////////////////////////////////////////// |
14 | CEventHandler::CEventHandler() |
15 | { |
16 | m_pGameServer = 0; |
17 | Clear(); |
18 | } |
19 | |
20 | void CEventHandler::SetGameServer(CGameContext *pGameServer) |
21 | { |
22 | m_pGameServer = pGameServer; |
23 | } |
24 | |
25 | void *CEventHandler::Create(int Type, int Size, CClientMask Mask) |
26 | { |
27 | if(m_NumEvents == MAX_EVENTS) |
28 | return 0; |
29 | if(m_CurrentOffset + Size >= MAX_DATASIZE) |
30 | return 0; |
31 | |
32 | void *p = &m_aData[m_CurrentOffset]; |
33 | m_aOffsets[m_NumEvents] = m_CurrentOffset; |
34 | m_aTypes[m_NumEvents] = Type; |
35 | m_aSizes[m_NumEvents] = Size; |
36 | m_aClientMasks[m_NumEvents] = Mask; |
37 | m_CurrentOffset += Size; |
38 | m_NumEvents++; |
39 | return p; |
40 | } |
41 | |
42 | void CEventHandler::Clear() |
43 | { |
44 | m_NumEvents = 0; |
45 | m_CurrentOffset = 0; |
46 | } |
47 | |
48 | void CEventHandler::Snap(int SnappingClient) |
49 | { |
50 | for(int i = 0; i < m_NumEvents; i++) |
51 | { |
52 | if(SnappingClient == SERVER_DEMO_CLIENT || m_aClientMasks[i].test(position: SnappingClient)) |
53 | { |
54 | CNetEvent_Common *pEvent = (CNetEvent_Common *)&m_aData[m_aOffsets[i]]; |
55 | if(!NetworkClipped(pGameServer: GameServer(), SnappingClient, CheckPos: vec2(pEvent->m_X, pEvent->m_Y))) |
56 | { |
57 | int Type = m_aTypes[i]; |
58 | int Size = m_aSizes[i]; |
59 | const char *pData = &m_aData[m_aOffsets[i]]; |
60 | if(GameServer()->Server()->IsSixup(ClientId: SnappingClient)) |
61 | EventToSixup(pType: &Type, pSize: &Size, ppData: &pData); |
62 | |
63 | void *pItem = GameServer()->Server()->SnapNewItem(Type, Id: i, Size); |
64 | if(pItem) |
65 | mem_copy(dest: pItem, source: pData, size: Size); |
66 | } |
67 | } |
68 | } |
69 | } |
70 | |
71 | void CEventHandler::EventToSixup(int *pType, int *pSize, const char **ppData) |
72 | { |
73 | static char s_aEventStore[128]; |
74 | if(*pType == NETEVENTTYPE_DAMAGEIND) |
75 | { |
76 | const CNetEvent_DamageInd *pEvent = (const CNetEvent_DamageInd *)(*ppData); |
77 | protocol7::CNetEvent_Damage *pEvent7 = (protocol7::CNetEvent_Damage *)s_aEventStore; |
78 | *pType = -protocol7::NETEVENTTYPE_DAMAGE; |
79 | *pSize = sizeof(*pEvent7); |
80 | |
81 | pEvent7->m_X = pEvent->m_X; |
82 | pEvent7->m_Y = pEvent->m_Y; |
83 | |
84 | pEvent7->m_ClientId = 0; |
85 | pEvent7->m_Angle = 0; |
86 | |
87 | // This will need some work, perhaps an event wrapper for damageind, |
88 | // a scan of the event array to merge multiple damageinds |
89 | // or a separate array of "damage ind" events that's added in while snapping |
90 | pEvent7->m_HealthAmount = 1; |
91 | |
92 | pEvent7->m_ArmorAmount = 0; |
93 | pEvent7->m_Self = 0; |
94 | |
95 | *ppData = s_aEventStore; |
96 | } |
97 | else if(*pType == NETEVENTTYPE_SOUNDGLOBAL) // No more global sounds for the server |
98 | { |
99 | const CNetEvent_SoundGlobal *pEvent = (const CNetEvent_SoundGlobal *)(*ppData); |
100 | protocol7::CNetEvent_SoundWorld *pEvent7 = (protocol7::CNetEvent_SoundWorld *)s_aEventStore; |
101 | |
102 | *pType = -protocol7::NETEVENTTYPE_SOUNDWORLD; |
103 | *pSize = sizeof(*pEvent7); |
104 | |
105 | pEvent7->m_SoundId = pEvent->m_SoundId; |
106 | pEvent7->m_X = pEvent->m_X; |
107 | pEvent7->m_Y = pEvent->m_Y; |
108 | |
109 | *ppData = s_aEventStore; |
110 | } |
111 | } |
112 | |