UFO: Alien Invasion
Loading...
Searching...
No Matches
e_event_actormove.cpp
Go to the documentation of this file.
1
4
5/*
6Copyright (C) 2002-2025 UFO: Alien Invasion.
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17See the GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23*/
24
25#include "../../../../client.h"
27#include "e_event_actormove.h"
28
33int CL_ActorDoMoveTime (const eventRegister_t* self, dbuffer* msg, eventTiming_t* eventTiming)
34{
35 int time = 0;
36
37 const int eventTime = eventTiming->nextTime;
38 const int number = NET_ReadShort(msg);
39 /* get le */
40 le_t* le = LE_Get(number);
41 if (!le)
42 LE_NotFoundError(number);
43
44 pos3_t pos;
45 VectorCopy(le->pos, pos);
46 byte crouchingState = LE_IsCrouched(le) ? 1 : 0;
47
49 if (le->stepList == nullptr) {
50 le->stepList = newStep;
51 le->stepIndex = 0;
52 } else {
53 /* append to the list */
54 leStep_t* step = le->stepList;
55 while (step) {
56 if (step->next == nullptr) {
57 step->next = newStep;
58 le->stepIndex++;
59 break;
60 }
61 step = step->next;
62 }
63 }
64
65 /* the end of this event is marked with a 0 */
66 while (NET_PeekLong(msg) != 0) {
67 newStep->steps = NET_ReadByte(msg);
68 if (newStep->steps >= MAX_ROUTE || newStep->steps < 0)
69 Com_Error(ERR_DROP, "CL_ActorDoMoveTime: Invalid step number: %i", newStep->steps);
70 const dvec_t dvec = NET_ReadShort(msg);
71 const byte dir = getDVdir(dvec);
73 VectorCopy(pos, oldPos);
74 PosAddDV(pos, crouchingState, dvec);
75 const int stepTime = LE_ActorGetStepTime(le, pos, oldPos, dir, NET_ReadShort(msg));
76 newStep->stepTimes[newStep->steps] = stepTime;
77 time += stepTime;
78 NET_ReadShort(msg);
79 }
80
81 /* skip the end of move marker */
82 NET_ReadLong(msg);
83
84 /* Also skip the final position */
85 NET_ReadByte(msg);
86 NET_ReadByte(msg);
87 NET_ReadByte(msg);
88
89 assert(NET_PeekByte(msg) == EV_NULL);
90
91 eventTiming->nextTime += time + 400;
92 newStep->lastMoveTime = eventTime;
93 newStep->lastMoveDuration = time;
94 return eventTime;
95}
96
104void CL_ActorDoMove (const eventRegister_t* self, dbuffer* msg)
105{
106 const int number = NET_ReadShort(msg);
107
108 /* get le */
109 le_t* le = LE_Get(number);
110 if (!le)
111 LE_NotFoundError(number);
112
113 if (!LE_IsActor(le))
114 Com_Error(ERR_DROP, "Can't move, LE doesn't exist or is not an actor (entnum: %i, type: %i)\n",
115 number, le->type);
116
117 /* lock this le for other events, the corresponding unlock is in LE_DoEndPathMove() */
118 LE_Lock(le);
119 if (le->isMoving()) {
120 if (le->pathLength == le->pathPos) {
122 } else {
123 Com_Error(ERR_DROP, "Actor (entnum: %i) on team %i is still moving (%i steps left). Times: %i, %i, %i",
124 le->entnum, le->team, le->pathLength - le->pathPos, le->startTime, le->endTime, cl.time);
125 }
126 }
127
128 int i = 0;
129 /* the end of this event is marked with a 0 */
130 while (NET_PeekLong(msg) != 0) {
131 NET_ReadByte(msg);
132 le->dvtab[i] = NET_ReadShort(msg);
133 if (getDVdir(le->dvtab[i]) != DIRECTION_FALL && LE_IsDead(le))
134 Com_Error(ERR_DROP, "Can't move, actor on team %i dead (entnum: %i)", le->team, number);
135 le->speed[i] = NET_ReadShort(msg);
136 le->pathContents[i] = NET_ReadShort(msg);
137 i++;
138 }
139 le->pathLength = i;
140
141 if (le->pathLength > MAX_ROUTE)
142 Com_Error(ERR_DROP, "Overflow in pathLength (entnum: %i)", number);
143
144 /* skip the end of move marker */
145 NET_ReadLong(msg);
146 /* Also get the final position */
147 NET_ReadGPos(msg, le->newPos);
148
149 if (VectorCompare(le->newPos, le->pos))
150 Com_Error(ERR_DROP, "start and end pos are the same (entnum: %i)", number);
151
152 /* activate PathMove function */
153 le->resetFloor();
154 if (LE_IsInvisible(le))
155 /* Hack: this relies on the visibility events interrupting the EV_ACTOR_MOVE event */
157 else
159 le->pathPos = 0;
160 le->startTime = cl.time;
161 le->endTime = cl.time;
162}
clientBattleScape_t cl
void LET_StartPathMove(le_t *le)
Change the actors animation to walking.
void LET_HiddenMove(le_t *le)
Handle move for invisible actors.
void LE_DoEndPathMove(le_t *le)
Ends the move of an actor.
int LE_ActorGetStepTime(const le_t *le, const pos3_t pos, const pos3_t oldPos, const int dir, const int speed)
void LE_SetThink(le_t *le, localEntityThinkFunc_t think)
void LE_Lock(le_t *le)
Markes a le_t struct as locked. Should be called at the beginning of an event handler on this le_t,...
le_t * LE_Get(int entnum)
Searches all local entities for the one with the searched entnum.
bool LE_IsActor(const le_t *le)
Checks whether the given le is a living actor.
#define LE_IsDead(le)
#define LE_IsCrouched(le)
#define LE_IsInvisible(le)
#define LE_NotFoundError(entnum)
Primary header for client.
void Com_Error(int code, const char *fmt,...)
Definition common.cpp:459
#define ERR_DROP
Definition common.h:211
#define MAX_ROUTE
Definition defines.h:84
#define DIRECTION_FALL
Definition defines.h:335
void CL_ActorDoMove(const eventRegister_t *self, dbuffer *msg)
Moves actor.
int CL_ActorDoMoveTime(const eventRegister_t *self, dbuffer *msg, eventTiming_t *eventTiming)
Decides if following events should be delayed. The delay is the amount of time the actor needs to wal...
#define PosAddDV(p, crouch, dv)
Definition mathlib.h:253
short dvec_t
The direction vector tells us where the actor came from (in his previous step). The pathing table hol...
Definition mathlib.h:236
#define getDVdir(dv)
Definition mathlib.h:249
#define Mem_AllocType(type)
Definition mem.h:39
int NET_ReadLong(dbuffer *buf)
Definition netpack.cpp:282
int NET_ReadByte(dbuffer *buf)
Reads a byte from the netchannel.
Definition netpack.cpp:234
int NET_ReadShort(dbuffer *buf)
Definition netpack.cpp:242
int NET_PeekLong(const dbuffer *buf)
Definition netpack.cpp:273
int NET_PeekByte(const dbuffer *buf)
Definition netpack.cpp:251
void NET_ReadGPos(dbuffer *buf, pos3_t pos)
Definition netpack.cpp:376
@ EV_NULL
Definition q_shared.h:80
QGL_EXTERN GLint i
Definition r_gl.h:113
Struct that defines one particular event with all its callbacks and data.
Definition e_main.h:42
CL_ParseEvent timers and vars.
Definition e_main.h:30
int nextTime
Definition e_main.h:31
a local entity
int startTime
void resetFloor()
dvec_t dvtab[MAX_ROUTE]
leStep_t * stepList
int speed[MAX_ROUTE]
pos3_t pos
int pathContents[MAX_ROUTE]
int pathPos
int stepIndex
int pathLength
int entnum
pos3_t newPos
entity_type_t type
int endTime
bool isMoving() const
int stepTimes[MAX_ROUTE]
int lastMoveDuration
struct leStep_s * next
pos_t pos3_t[3]
Definition ufotypes.h:58
static int oldPos
#define VectorCopy(src, dest)
Definition vector.h:51
#define VectorCompare(a, b)
Definition vector.h:63