1 /////////////////////////////////////////
2 //
3 //             OpenLieroX
4 //
5 // code under LGPL, based on JasonBs work,
6 // enhanced by Dark Charlie and Albert Zeyer
7 //
8 //
9 /////////////////////////////////////////
10 
11 
12 // Worm class
13 // Created 28/6/02
14 // Jason Boettcher
15 
16 
17 #ifndef __CWORM_H__
18 #define __CWORM_H__
19 
20 #include <cassert>
21 #include "LieroX.h" // for MAX_WORMS, _AI_DEBUG
22 #include "CProjectile.h"
23 #include "CNinjaRope.h"
24 #include "CWpnRest.h"
25 #include "Options.h" // for control_t
26 #include "Frame.h"
27 #include "DeprecatedGUI/CBar.h"
28 #include "CMap.h"
29 #include "CGameSkin.h"
30 #include "Entity.h"
31 #include "Version.h"
32 #include "DynDraw.h"
33 #include "CGameObject.h"
34 
35 // TODO: remove this after we changed network
36 #include "CBytestream.h"
37 
38 #ifdef _MSC_VER
39 // Warning: this used in member initializer list
40 #pragma warning(disable:4355)
41 #endif
42 
43 enum { MAX_WEAPONSLOTS = 10, MAX_WORM_NAME_LENGTH = 20, };
44 
45 // Direction
46 enum DIR_TYPE
47 {
48 	DIR_LEFT = 0,
49 	DIR_RIGHT = 1
50 };
51 
OppositeDir(DIR_TYPE d)52 inline DIR_TYPE OppositeDir(DIR_TYPE d) {
53 	switch(d) {
54 		case DIR_LEFT: return DIR_RIGHT;
55 		case DIR_RIGHT: return DIR_LEFT;
56 	}
57 	return DIR_LEFT;
58 }
59 
60 enum WRM_LIVES
61 {
62 	WRM_OUT = -1,
63 	WRM_UNLIM = -2
64 };
65 
66 // AI Game Type
67 enum GAM_AI_TYPE
68 {
69 	GAM_RIFLES	= 0,
70 	GAM_100LT	= 1,
71 	GAM_MORTARS	= 2,
72 	GAM_OTHER	= 3
73 };
74 
75 // Cells
76 enum CELL_TYPE
77 {
78 	CELL_CURRENT		= 0,
79 	CELL_LEFT			= 1,
80 	CELL_DOWN			= 2,
81 	CELL_RIGHT			= 3,
82 	CELL_UP				= 4,
83 	CELL_LEFTDOWN		= 5,
84 	CELL_RIGHTDOWN		= 6,
85 	CELL_LEFTUP			= 7,
86 	CELL_RIGHTUP		= 8
87 };
88 
89 struct WormType;
90 class CWpnRest;
91 class CGameScript;
92 struct weapon_t;
93 
94 // Weapon slot structure
95 struct wpnslot_t {
96 	const weapon_t	*Weapon;
97 	int			SlotNum;
98 	float		Charge;
99 	bool		Reloading;
100 	float		LastFire;
101 	bool		Enabled;
wpnslot_twpnslot_t102 	wpnslot_t() : Weapon(NULL), SlotNum(0), Charge(0), Reloading(false), LastFire(0), Enabled(false) {}
103 };
104 
105 struct randweapons_t {
106 	int Weap1, Weap2, Weap3, Weap4, Weap5;
107 };
108 
109 // the files have to be included yourself later
110 // they are used here; but their headers depends on this header
111 // TODO: remove the usage of these in this header
112 class CServerConnection;
113 class CBonus;
114 
115 
116 //    Artificial Intelligence
117 
118 // AI states
119 enum {
120     AI_THINK,
121     //AI_FINDTARGET,
122     AI_MOVINGTOTARGET,
123     AI_AIMING,
124     AI_SHOOTING
125 };
126 
127 // Target types
128 enum {
129     AIT_NONE,
130     AIT_WORM,
131     AIT_BONUS,
132     AIT_POSITION
133 };
134 
135 
136 class NEW_ai_node_t {
137 public:
138 	float fX, fY;
139 	NEW_ai_node_t *psPrev, *psNext;
140 };
141 
142 NEW_ai_node_t* get_last_ai_node(NEW_ai_node_t* n);
143 void delete_ai_nodes(NEW_ai_node_t* start);
144 void delete_ai_nodes(NEW_ai_node_t* start, NEW_ai_node_t* end);
145 float get_ai_nodes_length(NEW_ai_node_t* start);
146 // this do the same as the fct above except that it don't do the sqrt
147 float get_ai_nodes_length2(NEW_ai_node_t* start);
148 
149 class CWorm;
150 
151 class CWormInputHandler {
152 protected:
153 	CWorm* m_worm;
154 public:
CWormInputHandler(CWorm * w)155 	CWormInputHandler(CWorm* w) : m_worm(w) {}
~CWormInputHandler()156 	virtual ~CWormInputHandler() {}
157 
158 	virtual std::string name() = 0;
159 
160 	virtual void initWeaponSelection() = 0; // should reset at least bWeaponsReady
161 	virtual void doWeaponSelectionFrame(SDL_Surface * bmpDest, CViewport *v) = 0;
162 
163 	// simulation
startGame()164 	virtual void startGame() {}
165 	virtual void getInput() = 0;
clearInput()166     virtual void clearInput() {}
167 
onRespawn()168 	virtual void onRespawn() {}
169 };
170 
171 
172 struct WormJoinInfo;
173 
174 // TODO: split into classes: one for CClient and one for CServerConnection (latter only containing some general information, more like a simple struct)
175 class CWorm: public CGameObject {
176 	friend class CWormInputHandler;
177 	friend class CWormBotInputHandler;
178 	friend class CWormHumanInputHandler;
179 	friend struct WormJoinInfo;
180 public:
181 	CWorm();
182 	~CWorm();
183 
184 private:
185 	// disallow these!
CWorm(const CWorm &)186 	CWorm(const CWorm&): cSparkles(this) { assert(false); }
187 	CWorm& operator=(const CWorm&) { assert(false); return *this; }
188 
189 private:
190 	// Attributes
191 
192 	// General
193 	bool		bUsed;
194 	int			iID;
195 	WormType*	m_type;
196 	bool		bLocal;
197 	int			iTeam;
198 	std::string	sName;
199 	int			iRanking;
200 	bool		bAlreadyKilled;
201 	bool		bSpectating;
202 	bool		bSpawnedOnce;
203 
204 	// Client info
205 	int			iClientID;
206 	int			iClientWormID;
207 
208 
209 	// Simulation
210 	worm_state_t tState;
211 
212 	CVec		vLastPos;
213 	CVec		vDrawPos;
214 	bool		bOnGround;
215 	AbsTime		fLastInputTime;
216 	// last time we moved left or right
217 	AbsTime		lastMoveTime;
218 
219 
220 	TimeDiff	fServertime; // only for CServerConnection: when a wormupdate arrives, the servertime of client (>=beta8)
221 
222 	CVec		vFollowPos;
223 	bool		bFollowOverride;
224 
225     AbsTime		fLastCarve;
226 	AbsTime		fLastShoot;
227 
228 
229 	// Score
230 	int			iKills;
231 	int			iDeaths;
232 	int			iSuicides;
233 	int			iTeamkills;
234 	float		fDamage;
235 
236 	int			iTotalWins;
237 	int			iTotalLosses;
238 	int			iTotalKills;
239 	int			iTotalDeaths;
240 	int			iTotalSuicides;
241 	Version		cClientVersion;
242 
243 	// Game
244 	float		fLoadingTime;
245 	bool		bDrawMuzzle;
246 	int			iLives;
247 	bool		bAlive;
248 	AbsTime		fTimeofDeath;
249 	DIR_TYPE	iFaceDirectionSide;
250 	DIR_TYPE	iMoveDirectionSide;
251 	bool		bGotTarget;
252 	float		fAngle;
253     float       fAngleSpeed;
254     float		fMoveSpeedX;
255 	float		fSpeedFactor;
256 	bool		bCanUseNinja;
257 	float		fDamageFactor;
258 	float		fShieldFactor;
259 	bool		bCanAirJump; // For instant air jump
260 	AbsTime		fLastAirJumpTime; // For relative air-jump
261 	float		fFrame;
262 	CNinjaRope	cNinjaRope;
263 	profile_t	*tProfile;
264 	AbsTime		fRopeTime;
265 	std::vector<bool>	bVisibleForWorm;
266 	AbsTime		fVisibilityChangeTime;  // AbsTime when the worm was hidden/shown
267 
268 	bool		bHooked;
269 	CWorm		*pcHookWorm;
270 
271 	bool		bRopeDown;
272 	bool		bRopeDownOnce;
273 
274 	bool		bTagIT;
275 	TimeDiff	fTagTime;
276 	EntityEffect cSparkles;
277 
278     int         iDirtCount;
279 
280 	AbsTime		fLastBlood;
281 
282 
283 	// Owner client
284 	CServerConnection *cOwner;
285 
286 	// Network
287 	AbsTime		fFrameTimes[NUM_FRAMES];
288 
289 	// server
290 	worm_state_t tLastState; // Used for checking if we need to send the packet
291 	float		fLastAngle;
292 	AbsTime		fLastUpdateWritten;
293 	CVec		vLastUpdatedPos; // last pos we have send to client
294 		// client
295 	AbsTime		fLastPosUpdate;  // Used for velocity calculations (client does not send velocity)
296 	CVec		vOldPosOfLastPaket;
297 	CVec		vPreOldPosOfLastPaket;
298 	AbsTime		fPreLastPosUpdate;
299 	CVec		vLastEstimatedVel;
300 	CVec		vPreLastEstimatedVel;
301 	int			iLastCharge;
302 	int			iLastCurWeapon;
303 
304 	AbsTime		fSpawnTime;
305 	bool		bLobbyReady; // Lobby Ready state
306 
307 	// Graphics
308 	CWormSkin	cSkin;
309 	struct SkinDynDrawer; SkinDynDrawer* skinPreviewDrawerP;
310 	SmartPointer<DynDrawIntf> skinPreviewDrawer;
311 	SmartPointer<SDL_Surface> bmpGibs;
312 	DeprecatedGUI::CBar		cHealthBar;
313 	DeprecatedGUI::CBar		cWeaponBar;
314 
315 
316 	// Arsenal
317 	bool		bWeaponsReady;
318 	bool		bIsPrepared;
319 	bool		bGameReady;
320 	CGameScript	*cGameScript;
321     CWpnRest    *cWeaponRest;
322 	int			iNumWeaponSlots;
323 	int			iCurrentWeapon;
324 	wpnslot_t	tWeapons[MAX_WEAPONSLOTS];
325 	AFK_TYPE	iAFK;
326 	std::string	sAFKMessage;
327 
328     // Force the showing of the current weapon
329     bool        bForceWeapon_Name;
330     AbsTime       fForceWeapon_Time;
331 
332 	CWormInputHandler* m_inputHandler;
333 
334 	unsigned	iShotCount; // For server only, used as a random number for CShotList
335 
336 public:
337 	// Used to print damage numbers over the worm head
338 	struct DamageReport {
339 		float damage;
340 		AbsTime lastTime;
DamageReportDamageReport341 		DamageReport(): damage(0.0f), lastTime(AbsTime()) {}
342 	};
343 
344 private:
345 	std::map< int, DamageReport> cDamageReport; // WormID can be -1, then this is projectile generated by gamemode or level script
346 
347 public:
348 	// Methods
349 
350 
351 	//
352 	// General
353 	//
354 	void		Clear();
355 	void		Init();
356 	//void		CopyProfile(plyprofile_t *profile);
357 	void		Shutdown();
358 
359 
360 	// TODO: move this out here (to network engine)
361 	//
362 	// Network
363 	//
364 	void		writeInfo(CBytestream *bs);
365 	void		updateCheckVariables();
366 	bool		checkPacketNeeded();
367 	void		writePacket(CBytestream *bs, bool fromServer, CServerConnection* receiver);
368 	void		readPacket(CBytestream *bs, CWorm *worms);
369 	void		net_updatePos(const CVec& newpos);
370 	bool		skipPacket(CBytestream *bs);
371 	void		readPacketState(CBytestream *bs, CWorm *worms);
372 	static bool	skipPacketState(CBytestream *bs);
373 	void		writeWeapons(CBytestream *bs);
374 	void		readWeapons(CBytestream *bs);
skipWeapons(CBytestream * bs)375 	static bool	skipWeapons(CBytestream *bs)  { return bs->Skip(5); } // 5 weapons
376 	void		writeStatUpdate(CBytestream *bs);
377 	void		updateStatCheckVariables();
378 	bool		checkStatePacketNeeded();
379 	void		readStatUpdate(CBytestream *bs);
skipStatUpdate(CBytestream * bs)380 	static bool	skipStatUpdate(CBytestream *bs) { return bs->Skip(2); } // Current weapon and charge
381 	int			GetMyPing();
382 
383 
384 	void		setupLobby();
385 	void		loadDetails();
386 	void		saveDetails();
387 
388 
389 
390 	// Weapon
391 	void		GetRandomWeapons();
392 	void		CloneWeaponsFrom(CWorm* w);
393 
394 
395 	//
396 	// Graphics
397 	//
398 	bool		ChangeGraphics(int generalgametype);
399 	void		FreeGraphics();
400 	SmartPointer<SDL_Surface> ChangeGraphics(const std::string& filename, bool team);
401 	void		Draw(SDL_Surface * bmpDest, CViewport *v);
402     void        DrawShadow(SDL_Surface * bmpDest, CViewport *v);
403 	void		UpdateDrawPos();
404 
405 	//
406 	// Game
407 	//
isPrepared()408 	bool		isPrepared() { return bIsPrepared; }
409 	void		Prepare(bool serverSide); // weapon selection and so on
410 	void		Unprepare(); // after a game
411 	void		StartGame();
412 	void		Spawn(CVec position);
413 	bool		Kill();
414 	bool		CheckBonusCollision(CBonus *b);
415 	bool		GiveBonus(CBonus *b);
416 	void		Hide(int forworm, bool immediate);
417 	void		Show(int forworm, bool immediate);
418 
419 
420 	void		getInput();
421 	void		clearInput();
422 	void		initWeaponSelection();
423 	void		doWeaponSelectionFrame(SDL_Surface * bmpDest, CViewport *v);
424 
425 	void		setAiDiff(int aiDif);
426 
427 	//
428 	// Misc.
429 	//
430 	bool		CanType();
431 
432 	bool		isLocalHostWorm();
433 	bool		isFirstLocalHostWorm();
434 	bool		shouldDoOwnWeaponSelection();
435 
436 
437     int         traceLine(CVec target, float *fDist, int *nType, int divs = 5);
438 	int			traceLine(CVec target, CVec start, int *nType, int divs = 5, uchar checkflag = PX_EMPTY);
439 
440 	bool		IsEmpty(int Cell);
441     bool		CheckOnGround();
442 
443 
444 	//
445 	// Variables
446 	//
isUsed()447 	bool		isUsed()				{ return bUsed; }
448 	void		setUsed(bool _u);
449 
getNinjaRope()450 	CNinjaRope*	getNinjaRope()				{ return &cNinjaRope; }
451 
getName()452 	std::string getName()			{ return sName; }
setName(const std::string & val)453 	void		setName(const std::string& val) { sName = val; }
454 	Color		getGameColour();
setColour(Color c)455 	void		setColour(Color c)			{ cSkin.Colorize(c); }
setColour(Uint8 r,Uint8 g,Uint8 b)456 	void		setColour(Uint8 r, Uint8 g, Uint8 b) { cSkin.Colorize(Color(r,g,b)); }
457 
setLocal(bool _l)458 	void		setLocal(bool _l)			{ bLocal = _l; }
getLocal()459 	bool		getLocal()				{ return bLocal; }
460 
setSpawnedOnce()461 	void		setSpawnedOnce()			{ bSpawnedOnce = true; }
haveSpawnedOnce()462 	bool		haveSpawnedOnce()			{ return bSpawnedOnce; }
463 
getLives()464 	int			getLives()				{ return iLives; }
setLives(int l)465 	void		setLives(int l)				{ iLives = l; }
466 
getDamage()467 	float		getDamage()				{ return fDamage; }
setDamage(float l)468 	void		setDamage(float l)		{ fDamage = l; }
469 	void		addDamage(float damage, CWorm* victim, const GameOptions::GameInfo & settings);
470 
getKills()471 	int			getKills() const		{ return iKills; }
setKills(int k)472     void        setKills(int k)			{ iKills = k; }
addKill()473     void        addKill()				{ iKills++; }
474 
475 	int			getScore() const;		// Not same as getKills, takes into account suicides and deaths
476 
getDeaths()477 	int			getDeaths() const		{ return iDeaths; }
setDeaths(int d)478 	void		setDeaths(int d)		{ iDeaths = d; }
479 	void		addDeath();
480 
getSuicides()481 	int			getSuicides() const		{ return iSuicides; }
setSuicides(int d)482 	void		setSuicides(int d)		{ iSuicides = d; }
483 	void		addSuicide();
484 
getTeamkills()485 	int			getTeamkills() const	{ return iTeamkills; }
setTeamkills(int d)486 	void		setTeamkills(int d)		{ iTeamkills = d; }
487 	void		addTeamkill();
488 
setID(int i)489 	void		setID(int i)				{ iID = i; }
getID()490 	int			getID()	const			{ return iID; }
491 
getType()492 	WormType*	getType()				{ return m_type; }
setType(WormType * t)493     void        setType(WormType* t)        { m_type = t; }
494 
getAlive()495 	bool		getAlive()				{ return bAlive; }
setAlive(bool _a)496 	void		setAlive(bool _a)			{ bAlive = _a; }
497 
getTimeofDeath()498 	AbsTime		getTimeofDeath()		{ return fTimeofDeath; }
499 
setHooked(bool h,CWorm * w)500 	void		setHooked(bool h, CWorm *w)	{ bHooked=h; pcHookWorm=w; }
getHookedWorm()501 	CWorm		*getHookedWorm()			{ return pcHookWorm; }
setClient(CServerConnection * cl)502 	void		setClient(CServerConnection *cl)		{ cOwner = cl; }
getClient()503     CServerConnection     *getClient()            { return cOwner; }
504 
getFollowPos()505 	CVec		getFollowPos()			{ return (bFollowOverride?vFollowPos:vPos); }
resetFollow()506 	void		resetFollow()			{ bFollowOverride = false; }
doFollow(int x,int y)507 	void		doFollow(int x, int y)		{ bFollowOverride = true; vFollowPos.x = (float)x; vFollowPos.y = (float)y; }
508 
isOnGround()509 	bool		isOnGround()				{ return bOnGround; }
setOnGround(bool g)510 	void		setOnGround(bool g)			{ bOnGround = g; }
511 
getWormState()512 	worm_state_t *getWormState()		{ return &tState; }
513 
514 	bool		hasOwnServerTime();
serverTime()515 	TimeDiff	serverTime()				{ return fServertime; }
516 
517 	bool		isVisibleForWorm(int worm) const;
518 	void		setVisibleForWorm(int worm, bool visibility);
519 	bool		isVisibleForEverybody() const;
520 	bool		isVisible(const CViewport* v) const;
521 	bool		isVisible(CWorm* viewerWorm) const;
522 
getAngle()523 	float		getAngle()	const			{ return fAngle; }
setAngle(float a)524 	void		setAngle(float a)			{ fAngle = a; }
525 	void		resetAngleAndDir();
getFaceDirectionSide()526 	DIR_TYPE	getFaceDirectionSide() const		{ return iFaceDirectionSide; }
setFaceDirectionSide(DIR_TYPE d)527 	void		setFaceDirectionSide(DIR_TYPE d)	{ iFaceDirectionSide = d; }
getFaceDirection()528 	CVec		getFaceDirection() const {
529 		return CVec(cosf(getAngle() * ((float)PI/180)) * ((iFaceDirectionSide == DIR_LEFT) ? -1.0f : 1.0f),
530 					sinf(getAngle() * ((float)PI/180)) ); }
getMoveDirectionSide()531 	DIR_TYPE	getMoveDirectionSide()				{ return iMoveDirectionSide; }
getMoveDirection()532 	CVec		getMoveDirection() const {
533 		return CVec(cosf(getAngle() * ((float)PI/180)) * ((iMoveDirectionSide == DIR_LEFT) ? -1.0f : 1.0f),
534 					sinf(getAngle() * ((float)PI/180)) ); }
535 
setLoadingTime(float l)536 	void		setLoadingTime(float l)		{ fLoadingTime = l; }
getLoadingTime()537 	float		getLoadingTime()			{ return fLoadingTime; }
538 
setCanUseNinja(bool b)539 	void		setCanUseNinja(bool b) { bCanUseNinja = b; }
canUseNinja()540 	bool		canUseNinja() const { return bCanUseNinja; }
setSpeedFactor(float f)541 	void		setSpeedFactor(float f) { fSpeedFactor = f; }
speedFactor()542 	float		speedFactor() const { return fSpeedFactor; }
setDamageFactor(float f)543 	void		setDamageFactor(float f) { fDamageFactor = f; }
damageFactor()544 	float		damageFactor() const { return fDamageFactor; }
setShieldFactor(float f)545 	void		setShieldFactor(float f) { fShieldFactor = f; }
shieldFactor()546 	float		shieldFactor() const { return fShieldFactor; }
setCanAirJump(bool b)547 	void		setCanAirJump(bool b) { bCanAirJump = b; }
canAirJump()548 	bool		canAirJump() const { return bCanAirJump; }
setLastAirJumpTime(AbsTime t)549 	void		setLastAirJumpTime(AbsTime t) { fLastAirJumpTime = t; }
getLastAirJumpTime()550 	AbsTime		getLastAirJumpTime() { return fLastAirJumpTime; }
551 
getGameScript()552 	CGameScript* getGameScript()			{ return cGameScript; }
setGameScript(CGameScript * gs)553 	void		setGameScript(CGameScript *gs)	{ cGameScript = gs; }
setWpnRest(CWpnRest * wr)554     void        setWpnRest(CWpnRest *wr)    { cWeaponRest = wr; }
555 
setDrawMuzzle(bool _d)556 	void		setDrawMuzzle(bool _d)		{ bDrawMuzzle = _d; }
557 
getWeaponsReady()558 	bool		getWeaponsReady()		{ return bWeaponsReady; }
setWeaponsReady(bool _w)559 	void		setWeaponsReady(bool _w)	{ bWeaponsReady = _w; }
getCurWeapon()560 	wpnslot_t	*getCurWeapon()			{ return &tWeapons[MIN(iNumWeaponSlots, iCurrentWeapon)]; }
getCurrentWeapon()561 	int			getCurrentWeapon()		{ return MIN(iNumWeaponSlots, iCurrentWeapon); }
setCurrentWeapon(int _w)562 	void		setCurrentWeapon(int _w)	{ iCurrentWeapon = MIN(iNumWeaponSlots, _w); }
getWeapon(int id)563 	wpnslot_t	*getWeapon(int id)			{ return &tWeapons[id]; }
564 
setGameReady(bool _g)565 	void		setGameReady(bool _g)		{ bGameReady = _g; }
getGameReady()566 	bool		getGameReady()			{ return bGameReady; }
567 
setLobbyReady(bool _g)568 	void		setLobbyReady(bool _g)		{ bLobbyReady = _g; }
getLobbyReady()569 	bool		getLobbyReady() const		{ return bLobbyReady; }
570 
setProfile(profile_t * p)571 	void		setProfile(profile_t *p)	{ tProfile = p; }
getProfile()572 	profile_t	*getProfile()				{ return tProfile; }
573 
setTeam(int _t)574 	void		setTeam(int _t)				{ iTeam = _t; }
getTeam()575 	int			getTeam() const				{ return iTeam; }
576 
getGibimg()577 	SmartPointer<SDL_Surface> getGibimg()			{ return bmpGibs; }
getPicimg()578 	SmartPointer<DynDrawIntf> getPicimg()			{ return skinPreviewDrawer; }
579 
getTagIT()580 	bool		getTagIT()				{ return bTagIT; }
581 	void		setTagIT(bool _t);
582 
getLastBlood()583 	AbsTime		getLastBlood()				{ return fLastBlood; }
setLastBlood(const AbsTime & b)584 	void		setLastBlood(const AbsTime& b)		{ fLastBlood = b; }
getSparklesEffect()585 	EntityEffect * getSparklesEffect()		{ return &cSparkles; }
586 
587     void        incrementDirtCount(int d);
getDirtCount()588     int         getDirtCount()          { return iDirtCount; }
589 
getNumWeaponSlots()590 	int			getNumWeaponSlots() const { return iNumWeaponSlots; }
591 
setTarget(bool _t)592 	void		setTarget(bool _t)			{ bGotTarget = _t; }
593 
getTagTime()594 	TimeDiff	getTagTime()			{ return fTagTime; }
setTagTime(const TimeDiff & _t)595 	void		setTagTime(const TimeDiff& _t)		{ fTagTime = _t; }
incrementTagTime(const TimeDiff & dt)596 	void		incrementTagTime(const TimeDiff& dt)	{ fTagTime+=dt; }
597 
getSkin()598 	CWormSkin&	getSkin()				{ return cSkin; }
setSkin(const CWormSkin & skin)599 	void		setSkin(const CWormSkin& skin)	{ cSkin = skin; }
setSkin(const std::string & skin)600 	void		setSkin(const std::string& skin)	{ cSkin.Change(skin); }
601 
getAlreadyKilled()602 	bool		getAlreadyKilled()			{ return bAlreadyKilled; }
setAlreadyKilled(bool _k)603 	void		setAlreadyKilled(bool _k)	{ bAlreadyKilled = _k; }
604 
isShooting()605 	bool		isShooting()				{ return tState.bShoot; }
isWeaponReloading()606 	bool		isWeaponReloading()			{ return getCurWeapon()->Reloading; }
607 
isSpectating()608 	bool		isSpectating()				{ return bSpectating; }
setSpectating(bool _s)609 	void		setSpectating(bool _s)		{ bSpectating = _s; }
610 
getAFK()611 	AFK_TYPE	getAFK()				{ return iAFK; }
getAFKMessage()612 	const std::string & getAFKMessage()		{ return sAFKMessage; }
613 	void		setAFK(AFK_TYPE _f, const std::string & msg);
614 
615 	void	addTotalWins(int _w = 1)		{ iTotalWins += _w; }
getTotalWins()616 	int		getTotalWins()				{ return iTotalWins; }
617 	void	addTotalLosses(int _l = 1)		{ iTotalLosses += _l; }
getTotalLosses()618 	int		getTotalLosses()			{ return iTotalLosses; }
619 	void	addTotalKills(int _k = 1)		{ iTotalKills += _k; }
getTotalKills()620 	int		getTotalKills()				{ return iTotalKills; }
621 	void	addTotalDeaths(int _d = 1)		{ iTotalDeaths += _d; }
getTotalDeaths()622 	int		getTotalDeaths()			{ return iTotalDeaths; }
623 	void	addTotalSuicides(int _d = 1)	{ iTotalSuicides += _d; }
getTotalSuicides()624 	int		getTotalSuicides()			{ return iTotalSuicides; }
625 
getClientVersion()626 	const Version & getClientVersion()				{ return cClientVersion; }
setClientVersion(const Version & v)627 	void	setClientVersion(const Version & v)		{ cClientVersion = v; }
628 
629 
frame()630 	float&		frame()						{ return fFrame; }
631 
inputHandler()632 	CWormInputHandler* inputHandler() { return m_inputHandler; }
633 	void reinitInputHandler();
634 
getDamageReport()635 	std::map< int, DamageReport> & getDamageReport() { return cDamageReport; }
636 
getShotCount()637 	unsigned	getShotCount() const	{ return iShotCount; }
increaseShotCount()638 	void		increaseShotCount()		{ iShotCount++; }
639 	// HINT: saves the current time of the simulation
640 	// TODO: should be moved later to PhysicsEngine
641 	// but it's not possible in a clean way until we have no simulateWorms()
642 	// there which simulates all worms together
643 	AbsTime	fLastSimulationTime;
644 };
645 
646 
647 int traceWormLine(CVec target, CVec start, CVec* collision = NULL);
648 
649 struct WormJoinInfo {
WormJoinInfoWormJoinInfo650 	WormJoinInfo() : iTeam(0), m_type(NULL) {}
651 	void loadFromProfile(profile_t* p);
652 	void readInfo(CBytestream *bs);
skipInfoWormJoinInfo653 	static bool	skipInfo(CBytestream *bs)  { bs->SkipString(); bs->Skip(2); bs->SkipString(); return bs->Skip(3); }
654 	void applyTo(CWorm* worm) const;
655 
656 	std::string sName;
657 	int iTeam;
658 	WormType* m_type;
659 	std::string skinFilename;
660 	Color skinColor;
661 };
662 
663 #endif  //  __CWORM_H__
664