about summary refs log tree commit diff
path: root/src/game/gamecore.hpp
blob: 1f9dda81d2d96014af922b96ba9fae66d01ba700 (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
#ifndef GAME_GAME_H
#define GAME_GAME_H

#include <base/system.h>
#include <base/math.hpp>

#include <engine/e_common_interface.h>
#include <math.h>
#include "collision.hpp"
#include <game/generated/g_protocol.hpp>

struct TUNING_PARAMS
{
	TUNING_PARAMS()
	{
		const float ticks_per_second = 50.0f;
		#define MACRO_TUNING_PARAM(name,value) name.set((int)(value*100.0f));
		#include "tuning.hpp"
		#undef MACRO_TUNING_PARAM
	}

	static const char *names[];
	
	#define MACRO_TUNING_PARAM(name,value) tune_param name;
	#include "tuning.hpp"
	#undef MACRO_TUNING_PARAM
	
	static int num() { return sizeof(TUNING_PARAMS)/sizeof(int); }
	bool set(int index, float value);
	bool set(const char *name, float value);
	bool get(int index, float *value);
	bool get(const char *name, float *value);
};


inline vec2 get_direction(int angle)
{
	float a = angle/256.0f;
	return vec2(cosf(a), sinf(a));
}

inline vec2 get_dir(float a)
{
	return vec2(cosf(a), sinf(a));
}

inline float get_angle(vec2 dir)
{
	float a = atan(dir.y/dir.x);
	if(dir.x < 0)
		a = a+pi;
	return a;
}


inline vec2 calc_pos(vec2 p, vec2 v, float curvature, float speed, float t)
{
	vec2 n;
	t *= speed;
	n.x = p.x + v.x*t;
	n.y = p.y + v.y*t + curvature/10000*(t*t);
	return n;
}


template<typename T>
inline T saturated_add(T min, T max, T current, T modifier)
{
	if(modifier < 0)
	{
		if(current < min)
			return current;
		current += modifier;
		if(current < min)
			current = min;
		return current;
	}
	else
	{
		if(current > max)
			return current;
		current += modifier;
		if(current > max)
			current = max;
		return current;
	}
}

void move_point(vec2 *inout_pos, vec2 *inout_vel, float elasticity, int *bounces);
void move_box(vec2 *inout_pos, vec2 *inout_vel, vec2 size, float elasticity);
bool test_box(vec2 pos, vec2 size);
float velocity_ramp(float value, float start, float range, float curvature);

// hooking stuff
enum
{
	HOOK_RETRACTED=-1,
	HOOK_IDLE=0,
	HOOK_RETRACT_START=1,
	HOOK_RETRACT_END=3,
	HOOK_FLYING,
	HOOK_GRABBED,
	
	COREEVENT_GROUND_JUMP=0x01,
	COREEVENT_AIR_JUMP=0x02,
	COREEVENT_HOOK_LAUNCH=0x04,
	COREEVENT_HOOK_ATTACH_PLAYER=0x08,
	COREEVENT_HOOK_ATTACH_GROUND=0x10,
	COREEVENT_HOOK_RETRACT=0x20,
};

class WORLD_CORE
{
public:
	WORLD_CORE()
	{
		mem_zero(characters, sizeof(characters));
	}
	
	TUNING_PARAMS tuning;
	class CHARACTER_CORE *characters[MAX_CLIENTS];
};

class CHARACTER_CORE
{
public:
	WORLD_CORE *world;
	
	vec2 pos;
	vec2 vel;
	
	vec2 hook_pos;
	vec2 hook_dir;
	int hook_tick;
	int hook_state;
	int hooked_player;
	
	int jumped;
	NETOBJ_PLAYER_INPUT input;
	
	int triggered_events;
	
	void reset();
	void tick();
	void move();
	
	void read(const NETOBJ_CHARACTER_CORE *obj_core);
	void write(NETOBJ_CHARACTER_CORE *obj_core);
	void quantize();
};


#define LERP(a,b,t) (a + (b-a) * t)
#define min(a, b) ( a > b ? b : a)
#define max(a, b) ( a > b ? a : b)

inline bool col_check_point(float x, float y) { return col_is_solid((int)x, (int)y) != 0; }
inline bool col_check_point(vec2 p) { return col_check_point(p.x, p.y); }

#endif