-
Notifications
You must be signed in to change notification settings - Fork 4
/
missile.c
127 lines (107 loc) · 2.76 KB
/
missile.c
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
/* This file is part of punani-strike
* Copyright (c) 2011 Gianni Tedesco
* Released under the terms of GPLv3
*/
#include <punani/punani.h>
#include <punani/vec.h>
#include <punani/renderer.h>
#include <punani/light.h>
#include <punani/asset.h>
#include <punani/missile.h>
#include <punani/particles.h>
#include <punani/map.h>
#include <punani/entity.h>
#include <punani/cvar.h>
#include <math.h>
#include "ent-internal.h"
struct _missile {
struct _entity m_ent;
asset_file_t m_assets;
asset_t m_mesh;
particles_t m_trail;
float m_velocity;
unsigned int m_lifetime;
};
static void render(struct _entity *ent, renderer_t r, float lerp, light_t l)
{
struct _missile *m = (struct _missile *)ent;
//renderer_rotate(r, m->m_heading * (180.0 / M_PI), 0, 1, 0);
//asset_file_dirty_shadows(c->asset);
//asset_file_render_begin(c->asset, r, l);
//asset_render(m->m_mesh, r, l);
//asset_file_render_end(c->asset);
particles_emit(m->m_trail, m->m_ent.e_oldlerp, m->m_ent.e_lerp);
}
static void think(struct _entity *ent)
{
struct _missile *m = (struct _missile *)ent;
m->m_lifetime--;
if ( !m->m_lifetime || m->m_ent.e_origin[1] <= 0.0 ) {
entity_unlink(&m->m_ent);
return;
}
}
static void dtor(struct _entity *ent)
{
struct _missile *m = (struct _missile *)ent;
asset_put(m->m_mesh);
asset_file_close(m->m_assets);
particles_unref(m->m_trail);
free(m);
}
static void collide_world(struct _entity *ent, const vec3_t hit)
{
struct _missile *m = (struct _missile *)ent;
entity_unlink(&m->m_ent);
}
static const struct entity_ops ops = {
.e_flags = ENT_PROJECTILE,
.e_render = render,
.e_think = think,
.e_collide_world = collide_world,
.e_dtor = dtor,
};
missile_t missile_spawn(const vec3_t origin, const vec3_t angles)
{
struct _missile *m;
vec3_t a;
m = calloc(1, sizeof(*m));
if ( NULL == m )
return NULL;
m->m_assets = asset_file_open("data/missiles.db");
if ( NULL == m->m_assets )
goto err_free;
m->m_mesh = asset_file_get(m->m_assets, "AGR_71_Hydra.g");
if ( NULL == m->m_mesh )
goto err_free_assets;
m->m_trail = particles_new(1024);
if ( NULL == m->m_trail )
goto err_free_mesh;
m->m_lifetime = 100;
m->m_velocity = 12;
a[0] = angles[0];
a[1] = angles[1];
a[2] = angles[2];
entity_spawn(&m->m_ent, &ops, origin, NULL, a);
m->m_ent.e_move[0] += sin(m->m_ent.e_angles[1]);
m->m_ent.e_move[1] = -sin(m->m_ent.e_angles[0]);
m->m_ent.e_move[2] += cos(m->m_ent.e_angles[1]);
v_normalize(m->m_ent.e_move);
v_scale(m->m_ent.e_move, m->m_velocity);
entity_link(&m->m_ent);
/* success */
//con_printf("Missile away: %f %f %f\n",
// m->m_ent.e_origin[0],
// m->m_ent.e_origin[1],
// m->m_ent.e_origin[2]);
goto out;
err_free_mesh:
asset_put(m->m_mesh);
err_free_assets:
asset_file_close(m->m_assets);
err_free:
free(m);
m = NULL;
out:
return m;
}