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
4#include "laser_data.h"
5
6#include <engine/shared/snapshot.h>
7#include <game/client/prediction/gameworld.h>
8#include <game/generated/protocol.h>
9
10#include <game/collision.h>
11
12CLaserData ExtractLaserInfo(int NetObjType, const void *pData, CGameWorld *pGameWorld, const CNetObj_EntityEx *pEntEx)
13{
14 CLaserData Result = {.m_From: vec2(0, 0)};
15
16 if(NetObjType == NETOBJTYPE_DDNETLASER)
17 {
18 Result = ExtractLaserInfoDDNet(pLaser: (const CNetObj_DDNetLaser *)pData, pGameWorld);
19 }
20 else
21 {
22 CNetObj_Laser *pLaser = (CNetObj_Laser *)pData;
23
24 Result.m_From.x = pLaser->m_FromX;
25 Result.m_From.y = pLaser->m_FromY;
26 Result.m_To.x = pLaser->m_X;
27 Result.m_To.y = pLaser->m_Y;
28 Result.m_StartTick = pLaser->m_StartTick;
29 Result.m_ExtraInfo = false;
30 Result.m_Owner = -1;
31 Result.m_Type = -1;
32 Result.m_SwitchNumber = 0;
33 Result.m_Subtype = -1;
34 Result.m_TuneZone = pGameWorld && pGameWorld->m_WorldConfig.m_UseTuneZones ? pGameWorld->Collision()->IsTune(Index: pGameWorld->Collision()->GetMapIndex(Pos: Result.m_From)) : 0;
35 Result.m_Predict = true;
36 }
37
38 if(pEntEx && !(NetObjType == NETOBJTYPE_DDNETLASER && Result.m_SwitchNumber >= 0))
39 {
40 Result.m_SwitchNumber = pEntEx->m_SwitchNumber;
41 if(pEntEx->m_EntityClass == ENTITYCLASS_LIGHT)
42 {
43 Result.m_Type = LASERTYPE_FREEZE;
44 }
45 else if(pEntEx->m_EntityClass >= ENTITYCLASS_GUN_NORMAL && pEntEx->m_EntityClass <= ENTITYCLASS_GUN_UNFREEZE)
46 {
47 Result.m_Type = LASERTYPE_GUN;
48 }
49 else if(pEntEx->m_EntityClass >= ENTITYCLASS_DRAGGER_WEAK && pEntEx->m_EntityClass <= ENTITYCLASS_DRAGGER_STRONG)
50 {
51 Result.m_Type = LASERTYPE_DRAGGER;
52 }
53 else if(pEntEx->m_EntityClass == ENTITYCLASS_DOOR)
54 {
55 Result.m_Type = LASERTYPE_DOOR;
56 }
57 }
58
59 return Result;
60}
61
62CLaserData ExtractLaserInfoDDNet(const CNetObj_DDNetLaser *pLaser, CGameWorld *pGameWorld)
63{
64 CLaserData Result = {.m_From: vec2(0, 0)};
65 Result.m_From.x = pLaser->m_FromX;
66 Result.m_From.y = pLaser->m_FromY;
67 Result.m_To.x = pLaser->m_ToX;
68 Result.m_To.y = pLaser->m_ToY;
69 Result.m_StartTick = pLaser->m_StartTick;
70 Result.m_ExtraInfo = true;
71 Result.m_Owner = pLaser->m_Owner;
72 Result.m_Type = pLaser->m_Type;
73 Result.m_SwitchNumber = pLaser->m_SwitchNumber;
74 Result.m_Subtype = pLaser->m_Subtype;
75 Result.m_TuneZone = pGameWorld && pGameWorld->m_WorldConfig.m_UseTuneZones ? pGameWorld->Collision()->IsTune(Index: pGameWorld->Collision()->GetMapIndex(Pos: Result.m_From)) : 0;
76 Result.m_Predict = !(pLaser->m_Flags & LASERFLAG_NO_PREDICT);
77 return Result;
78}
79