aboutsummaryrefslogtreecommitdiff
path: root/src/entities/generale.c
blob: 728d9aa6687eda5dc8d1e096fe973e43c4e7f700 (plain)
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
#include "generale.h"
#include "assets.h"
#include "game.h"

void initGenerale(Entity * entity, Game * game) {
	entity->model = &game->assets.models[GENERALE_ASSET];
	entity->collisionModel = entityCreateCollisionModel(*entity->model);
	entity->transformedCollisionModel = entityCreateCollisionModel(*entity->model);
	setEntityRadius(entity);

	entity->velocity.angularVelocity = (AxisAngle){
		.axis = (Vector3){0.0, 1.0, 0.0},
		.angle = PI/2.0
	};

	// Allocate data.
	entity->data = KF_MALLOC(sizeof(Generale));

	if (entity->data == NULL) {
		ALLOCATION_ERROR;
		return;
	}

	Generale * data = (Generale*)entity->data;

	data->flyToPoint = (EntityFlyToPointInfo){
		.controller.bangbang.speed = 100.0,
		.controller.bangbang.stopAt = 0.0,
		.controlType = ENTITY_FLY_TO_POINT_BANG_BANG,
		.rotationSpeed = 0.0,
		.applyRotation = false
	};

	data->zigzag = GENERALE_ZIG;
	data->targetNotSet = true;
}

void closeGenerale(Entity * entity) {
	if (entity->data != NULL)
		KF_FREE(entity->data);

	entityFreeCollisionModel(entity->collisionModel);
	entityFreeCollisionModel(entity->transformedCollisionModel);
}

void updateGenerale(Game * game, Entity * entity) {
	entityUpdateLastValues(entity);

	Generale * data = (Generale*)entity->data;

	// Next point.
	if (data->targetNotSet) {
		getTargetGenerale(game, entity);
		data->targetNotSet = false;
	} else if (Vector3Distance(entity->position, data->target) <= GENERALE_NEXT_POINT_THRESHOLD)
		getTargetGenerale(game, entity);

	entityFlyToPoint(
		entity,
		data->target,
		&data->flyToPoint
	);

	// Spin this fucker.
	entityUpdateRotation(entity);

	entityCheckTransformedCollisionModel(entity);
}

void drawGenerale(Game * game, Entity * entity) {
	entityDraw(entity);

	//Generale * data = (Generale*)entity->data;

	//DrawLine3D(
	//	entity->position,
	//	data->target,
	//	BLUE
	//);

	//DrawCubeV(data->target, Vector3One(), BLUE);
}

void getTargetGenerale(Game * game, Entity * entity) {
	Entity * player = getEntityFromWorld(game->world, 0);
	Generale * data = (Generale*)entity->data;

	Vector3 dis = Vector3Subtract(player->position, entity->position);
	Vector3 dir = Vector3Normalize(dis);

	SetRandomSeed(time(NULL));
	float targetDis = GetRandomValue(GENERALE_ZIGZAG_SIZE_MIN, GENERALE_ZIGZAG_SIZE_MAX);
	float distance = Vector3Distance(entity->position, player->position);

	if (distance < targetDis)
		targetDis = distance;

	if (data->zigzag == GENERALE_ZIG) {
		dir = Vector3RotateByAxisAngle(dir, Vector3One(), PI/4);
		data->zigzag = GENERALE_ZAG;
	} else {
		dir = Vector3RotateByAxisAngle(dir, Vector3One(), -PI/4);
		data->zigzag = GENERALE_ZIG;
	}

	dir = Vector3Scale(dir, targetDis);
	data->target = Vector3Add(entity->position, dir);
}