File: FPSUnitController.cpp

package info (click to toggle)
spring 98.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 41,928 kB
  • ctags: 60,665
  • sloc: cpp: 356,167; ansic: 39,434; python: 12,228; java: 12,203; awk: 5,856; sh: 1,719; xml: 997; perl: 405; php: 253; objc: 194; makefile: 72; sed: 2
file content (129 lines) | stat: -rw-r--r-- 3,514 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#include "FPSUnitController.h"

#include "UI/MouseHandler.h"
#include "Game/Camera.h"
#include "Game/GlobalUnsynced.h"
#include "Game/TraceRay.h"
#include "Sim/Features/Feature.h"
#include "Sim/Misc/TeamHandler.h"
#include "Sim/Units/Unit.h"
#include "Sim/Units/Scripts/CobInstance.h"
#include "Sim/Weapons/Weapon.h"
#include "System/myMath.h"
#include "Net/Protocol/NetProtocol.h"

#include <SDL_mouse.h>


FPSUnitController::FPSUnitController()
	: targetUnit(NULL)
	, controllee(NULL)
	, controller(NULL)
	, viewDir(FwdVector)
	, targetPos(FwdVector)
	, targetDist(1000.0f)
	, forward(false)
	, back(false)
	, left(false)
	, right(false)
	, mouse1(false)
	, mouse2(false)
	, oldHeading(0)
	, oldPitch(0)
	, oldState(255)
	, oldDCpos(ZeroVector)
{
}



void FPSUnitController::Update() {
	const int piece = controllee->script->AimFromWeapon(0);
	const float3 relPos = controllee->script->GetPiecePos(piece);
	const float3 pos = controllee->GetObjectSpacePos(relPos) + (UpVector * 7.0f);

	oldDCpos = pos;

	CUnit* hitUnit;
	CFeature* hitFeature;

	// SYNCED, do NOT use GuiTraceRay which also checks gu->spectatingFullView
	float hitDist = TraceRay::TraceRay(pos, viewDir, controllee->maxRange, Collision::NOCLOAKED, controllee, hitUnit, hitFeature);

	if (hitUnit != NULL) {
		targetUnit = hitUnit;
		targetDist = hitDist;
		targetPos  = hitUnit->pos;

		if (!mouse2) {
			controllee->AttackUnit(hitUnit, true, true, true);
		}
	} else {
		hitDist = std::min(hitDist, controllee->maxRange * 0.95f);

		targetUnit = NULL;
		targetDist = hitDist;
		targetPos  = pos + viewDir * targetDist;

		if (!mouse2) {
			// if a target position is in range, but not on the ground,
			// projectiles can gain extra flighttime and travel further
			//
			// NOTE: CWeapon::AttackGround checks range via TryTarget
			if ((targetPos.y - CGround::GetHeightReal(targetPos.x, targetPos.z)) <= SQUARE_SIZE) {
				controllee->AttackGround(targetPos, true, true, true);
			}
		}
	}
}



void FPSUnitController::RecvStateUpdate(const unsigned char* buf) {
	forward    = !!(buf[2] & (1 << 0));
	back       = !!(buf[2] & (1 << 1));
	left       = !!(buf[2] & (1 << 2));
	right      = !!(buf[2] & (1 << 3));
	mouse1     = !!(buf[2] & (1 << 4));

	const bool newMouse2 = !!(buf[2] & (1 << 5));

	if (!mouse2 && newMouse2 && controllee != NULL) {
		controllee->AttackUnit(NULL, true, true, true);
	}

	mouse2 = newMouse2;

	const short int h = *((short int*) &buf[3]);
	const short int p = *((short int*) &buf[5]);

	viewDir = GetVectorFromHAndPExact(h, p);
}

void FPSUnitController::SendStateUpdate() {
	if (!gu->fpsMode)
		return;

	const bool* camMoveState = camera->GetMovState();
	const CMouseHandler::ButtonPressEvt* mouseButtons = mouse->buttons;

	unsigned char state = 0;
	state |= ((camMoveState[CCamera::MOVE_STATE_FWD]) * (1 << 0));
	state |= ((camMoveState[CCamera::MOVE_STATE_BCK]) * (1 << 1));
	state |= ((camMoveState[CCamera::MOVE_STATE_LFT]) * (1 << 2));
	state |= ((camMoveState[CCamera::MOVE_STATE_RGT]) * (1 << 3));
	state |= ((mouseButtons[SDL_BUTTON_LEFT ].pressed) * (1 << 4));
	state |= ((mouseButtons[SDL_BUTTON_RIGHT].pressed) * (1 << 5));

	shortint2 hp = GetHAndPFromVector(camera->forward);

	if (hp.x != oldHeading || hp.y != oldPitch || state != oldState) {
		oldHeading = hp.x;
		oldPitch   = hp.y;
		oldState   = state;

		net->Send(CBaseNetProtocol::Get().SendDirectControlUpdate(gu->myPlayerNum, state, hp.x, hp.y));
	}
}