large update. cleaned up some code. added new effects for almost everything

This commit is contained in:
Magnus Auvinen 2008-01-29 21:39:41 +00:00
parent 0dab7db963
commit 7bc733dc10
27 changed files with 719 additions and 556 deletions

BIN
data/particles.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -27,25 +27,10 @@ struct soundset {
array:sound sounds = *
}
struct particleinfo {
ptr:sprite spr = sprite@1
float color_r = color@1
float color_g = color@2
float color_b = color@3
float color_a = color@4
int lifemod = life@1
}
struct spriteptr {
ptr:sprite psprite = @0
}
struct projectileparticles {
int particlespersecond = particlespersecond@1
float particlesize = particlesize@1
float particlelife = particlelife@1
}
struct weapon {
ptr:sprite sprite_body = sprite_body@1
ptr:sprite sprite_cursor = sprite_cursor@1
@ -85,12 +70,9 @@ struct data_container {
array:spriteset spritesets = sprites.*
array:sprite sprites = sprites.*.*
array:weapon weapons = weapons.*
array:particleinfo particles = particles.*
array:projectileparticles projectileinfo = projectileparticles.*
array:soundset sounds = sounds.*
array:animation animations = animations.*
}
const array:int weapon = weapons.*

View file

@ -223,6 +223,10 @@ images {
filename "data/game.png"
}
particles {
filename "data/particles.png"
}
cursor {
filename "data/gui_cursor.png"
}
@ -240,62 +244,6 @@ images {
}
}
particles {
part1 {
sprite sprites.game.part1
color 0.7 0.7 0.7 1.0
life 50
}
part2 {
sprite sprites.game.part2
color 1.0 1.0 1.0 1.0
life 50
}
part3 {
sprite sprites.game.part3
color 0.8 0.8 0.8 1.0
life 50
}
part4 {
sprite sprites.game.part4
color 0.98 0.1 0.16 1.0
life 70
}
part5 {
sprite sprites.game.part5
color 1.0 1.0 1.0 1.0
life 70
}
part6 {
sprite sprites.game.part6
color 0.6 0.6 0.6 1.0
life 100
}
part7 {
sprite sprites.game.part7
color 1.0 1.0 1.0 1.0
life 100
}
part8 {
sprite sprites.game.part8
color 0.7 0.7 0.7 1.0
life 150
}
part9 {
sprite sprites.game.part9
color 1.0 1.0 1.0 1.0
life 40
}
}
powerups {
health {
amount 1
@ -319,44 +267,6 @@ powerups {
}
}
projectileparticles {
gun {
particlespersecond 200
particlesize 16.0
particlelife 0.5
}
rocket {
particlespersecond 100
particlesize 22.0
particlelife 1.3
}
shotgun {
particlespersecond 100
particlesize 16.0
particlelife 0.8
}
empty1 {
particlespersecond 300
particlesize 8.0
particlelife 0.8
}
empty2 {
particlespersecond 300
particlesize 8.0
particlelife 0.8
}
empty3 {
particlespersecond 300
particlesize 8.0
particlelife 0.8
}
sniper {
particlespersecond 300
particlesize 8.0
particlelife 0.8
}
}
weapons {
hammer {
sprite_body sprites.game.weapon_hammer_body
@ -507,37 +417,6 @@ weapons {
overchargetime 10.0
}
bomb {
sprite_body sprites.game.weapon_rocket_body
sprite_cursor sprites.game.weapon_rocket_cursor
sprite_proj sprites.game.weapon_rocket_proj
sprite_muzzles {
sprites.game.weapon_shotgun_muzzle1
sprites.game.weapon_shotgun_muzzle2
sprites.game.weapon_shotgun_muzzle3
}
nummuzzlesprites 3
muzzleoffsetx 0.0
muzzleoffsety 0.0
maxammo 10
costammo 1
recoil 10
firedelay 800
muzzleduration 0
visual_size 128
offsetx 24.0
offsety -2.0
meleedamage 0
meleereach 0
ammoregentime 0
duration -1
movetime 0
velocity 0
chargetime 1.0
overchargetime 10.0
}
ninja {
sprite_body sprites.game.weapon_ninja_body
sprite_cursor sprites.game.weapon_ninja_cursor
@ -572,6 +451,20 @@ weapons {
}
sprites {
particles images.particles 8 8 {
part_slice 0 0 1 1
part_ball 1 0 1 1
part_splat01 2 0 1 1
part_splat02 3 0 1 1
part_splat03 4 0 1 1
part_smoke 0 1 1 1
part_shell 0 2 2 2
part_expl01 0 4 4 4
part_airjump 2 2 2 2
}
game images.game 32 16 {
health_full 21 0 2 2

View file

@ -163,7 +163,7 @@ int gfx_init()
/* open window */
if(config.gfx_fullscreen)
{
int result = glfwOpenWindow(screen_width, screen_height, 8, 8, 8, 0, 24, 0, GLFW_FULLSCREEN);
int result = glfwOpenWindow(screen_width, screen_height, 8, 8, 8, 8, 24, 8, GLFW_FULLSCREEN);
if(result != GL_TRUE)
{
dbg_msg("game", "failed to create gl context");
@ -172,19 +172,22 @@ int gfx_init()
}
else
{
int result = glfwOpenWindow(screen_width, screen_height, 0, 0, 0, 0, 24, 0, GLFW_WINDOW);
int result = glfwOpenWindow(screen_width, screen_height, 0, 0, 0, 8, 24, 8, GLFW_WINDOW);
if(result != GL_TRUE)
{
dbg_msg("game", "failed to create gl context");
return 0;
}
}
glfwSetWindowSizeCallback(screen_resize);
glGetIntegerv(GL_ALPHA_BITS, &i);
dbg_msg("gfx", "alphabits = %d", i);
glGetIntegerv(GL_DEPTH_BITS, &i);
dbg_msg("gfx", "depthbits = %d", i);
glGetIntegerv(GL_STENCIL_BITS, &i);
dbg_msg("gfx", "stencilbits = %d", i);
glfwSetWindowTitle("Teewars");
@ -212,6 +215,10 @@ int gfx_init()
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* glAlphaFunc(GL_GREATER, 0);
glEnable(GL_ALPHA_TEST);*/
gfx_mask_op(MASK_NONE, 0);
/* Set all z to -5.0f */
@ -325,6 +332,8 @@ void gfx_set_vsync(int val)
int gfx_unload_texture(int index)
{
if(index < 0)
return 0;
glDeleteTextures(1, &textures[index].tex);
textures[index].next = first_free_texture;
memory_usage -= textures[index].memsize;

View file

@ -524,6 +524,9 @@ void mem_debug_dump();
int mem_allocated();
void swap_endian(void *data, unsigned elem_size, unsigned num);
/* #define cache_prefetch(addr) __builtin_prefetch(addr) */
#ifdef __cplusplus
}
#endif

View file

@ -13,6 +13,7 @@ extern "C" {
#include "../g_game.h"
#include "../g_version.h"
#include "../g_layers.h"
#include "../g_math.h"
#include "gc_map_image.h"
#include "../generated/gc_data.h"
#include "gc_menu.h"
@ -23,6 +24,8 @@ extern "C" {
#include "gc_anim.h"
#include "gc_console.h"
#include <GL/gl.h>
struct data_container *data = 0;
static int64 debug_firedelay = 0;
@ -87,6 +90,15 @@ void snd_play_random(int chn, int setid, float vol, vec2 pos)
set->last = id;
}
void send_switch_team(int team)
{
msg_pack_start(MSG_SETTEAM, MSGFLAG_VITAL);
msg_pack_int(team);
msg_pack_end();
client_send_msg();
}
class damage_indicators
{
public:
@ -179,159 +191,6 @@ void render_damage_indicators()
dmgind.render();
}
class particle_system
{
public:
struct particle
{
vec2 pos;
vec2 vel;
float life;
float max_life;
float size;
float rot;
float rotspeed;
float gravity;
float friction;
int iparticle;
vec4 color;
};
enum
{
MAX_PARTICLES=1024,
};
particle particles[MAX_PARTICLES];
int num_particles;
particle_system()
{
num_particles = 0;
}
void new_particle(vec2 pos, vec2 vel, float life, float size, float gravity, float friction, vec4 color=vec4(1,1,1,1))
{
if (num_particles >= MAX_PARTICLES)
return;
particles[num_particles].iparticle = rand() % data->num_particles;
particles[num_particles].pos = pos;
particles[num_particles].vel = vel;
particles[num_particles].life = life - (data->particles[particles[num_particles].iparticle].lifemod/100.0f) * life;
particles[num_particles].size = size;
particles[num_particles].max_life = life;
particles[num_particles].gravity = gravity;
particles[num_particles].friction = friction;
particles[num_particles].rot = frandom()*pi*2;
particles[num_particles].rotspeed = frandom() * 10.0f;
particles[num_particles].color = color;
num_particles++;
}
void update(float time_passed)
{
for(int i = 0; i < num_particles; i++)
{
particles[i].vel.y += particles[i].gravity*time_passed;
particles[i].vel *= particles[i].friction;
vec2 vel = particles[i].vel*time_passed;
move_point(&particles[i].pos, &vel, 0.1f+0.9f*frandom(), NULL);
particles[i].vel = vel* (1.0f/time_passed);
particles[i].life += time_passed;
particles[i].rot += time_passed * particles[i].rotspeed;
// check particle death
if(particles[i].life > particles[i].max_life)
{
num_particles--;
particles[i] = particles[num_particles];
i--;
}
}
}
void render()
{
gfx_blend_additive();
gfx_texture_set(data->images[IMAGE_GAME].id);
gfx_quads_begin();
for(int i = 0; i < num_particles; i++)
{
int type = particles[i].iparticle;
select_sprite(data->particles[type].spr);
float a = 1 - particles[i].life / particles[i].max_life;
vec2 p = particles[i].pos;
gfx_quads_setrotation(particles[i].rot);
gfx_setcolor(
data->particles[type].color_r * particles[i].color.r,
data->particles[type].color_g * particles[i].color.g,
data->particles[type].color_b * particles[i].color.b,
pow(a, 0.75f) * particles[i].color.a);
gfx_quads_draw(p.x, p.y,particles[i].size,particles[i].size);
}
gfx_quads_end();
gfx_blend_normal();
}
};
static particle_system temp_system;
class projectile_particles
{
public:
enum
{
LISTSIZE = 1000,
};
// meh, just use size %
int lastadd[LISTSIZE];
projectile_particles()
{
reset();
}
void reset()
{
for (int i = 0; i < LISTSIZE; i++)
lastadd[i] = -1000;
}
void addparticle(int projectiletype, int projectileid, vec2 pos, vec2 vel)
{
int particlespersecond = data->projectileinfo[projectiletype].particlespersecond;
int lastaddtick = lastadd[projectileid % LISTSIZE];
if(!particlespersecond)
return;
if ((client_tick() - lastaddtick) > (client_tickspeed() / particlespersecond))
{
lastadd[projectileid % LISTSIZE] = client_tick();
float life = data->projectileinfo[projectiletype].particlelife;
float size = data->projectileinfo[projectiletype].particlesize;
vec2 v = vel * 0.2f + normalize(vec2(frandom()-0.5f, -frandom()))*(32.0f+frandom()*32.0f);
// add the particle (from projectiletype later on, but meh...)
temp_system.new_particle(pos, v, life, size, 0, 0.95f);
}
}
};
static projectile_particles proj_particles;
void reset_projectile_particles() // TODO: remove
{
proj_particles.reset();
}
static char chat_input[512];
static unsigned chat_input_len;
static const int chat_max_lines = 10;
@ -391,16 +250,7 @@ void chat_add_line(int client_id, int team, const char *line)
killmsg killmsgs[killmsg_max];
int killmsg_current = 0;
void effect_air_jump(vec2 pos)
{
const int count = 12;
for(int i = 0; i <= count; i++)
{
float a = i/(float)count;
vec2 v = vec2((a-0.5f)*512.0f, 0);
temp_system.new_particle(pos+vec2(0,28), v, 0.4f, 16.0f, 0, 0.985f, vec4(0.25f,0.4f,1,1));
}
}
//bool add_trail = false;
extern int render_popup(const char *caption, const char *text, const char *button_text);
@ -425,107 +275,22 @@ void process_events(int snaptype)
else if(item.type == EVENT_EXPLOSION)
{
ev_explosion *ev = (ev_explosion *)data;
vec2 p(ev->x, ev->y);
// center explosion
temp_system.new_particle(p, vec2(0,0), 0.3f, 96.0f, 0, 0.95f);
temp_system.new_particle(p, vec2(0,0), 0.3f, 64.0f, 0, 0.95f);
temp_system.new_particle(p, vec2(0,0), 0.3f, 32.0f, 0, 0.95f);
temp_system.new_particle(p, vec2(0,0), 0.3f, 16.0f, 0, 0.95f);
for(int i = 0; i < 16; i++)
{
vec2 v = normalize(vec2(frandom()-0.5f, frandom()-0.5f))*(128.0f+frandom()*128.0f);
temp_system.new_particle(p, v, 0.2f+0.25f*frandom(), 16.0f, 0, 0.985f);
}
for(int i = 0; i < 16; i++)
{
vec2 v = normalize(vec2(frandom()-0.5f, frandom()-0.5f))*(256.0f+frandom()*512.0f);
temp_system.new_particle(p, v, 0.2f+0.25f*frandom(), 16.0f, 128.0f, 0.985f);
}
for(int i = 0; i < 64; i++)
{
vec2 v = normalize(vec2(frandom()-0.5f, frandom()-0.5f))*(frandom()*256.0f);
temp_system.new_particle(p, v, 0.2f+0.25f*frandom(), 24.0f, 128.0f, 0.985f);
}
effect_explosion(vec2(ev->x, ev->y));
}
else if(item.type == EVENT_SMOKE)
{
ev_explosion *ev = (ev_explosion *)data;
vec2 p(ev->x, ev->y);
// center explosion
vec2 v = normalize(vec2(frandom()-0.5f, -frandom()))*(32.0f+frandom()*32.0f);
temp_system.new_particle(p, v, 1.2f, 64.0f, 0, 0.95f);
v = normalize(vec2(frandom()-0.5f, -frandom()))*(128.0f+frandom()*128.0f);
temp_system.new_particle(p, v, 1.2f, 32.0f, 0, 0.95f);
v = normalize(vec2(frandom()-0.5f, -frandom()))*(128.0f+frandom()*128.0f);
temp_system.new_particle(p, v, 1.2f, 16.0f, 0, 0.95f);
for(int i = 0; i < 8; i++)
{
vec2 v = normalize(vec2(frandom()-0.5f, frandom()-0.5f))*(64.0f+frandom()*64.0f);
temp_system.new_particle(p, v, 0.5f+0.5f*frandom(), 16.0f, 0, 0.985f);
}
for(int i = 0; i < 8; i++)
{
vec2 v = normalize(vec2(frandom()-0.5f, frandom()-0.5f))*(128.0f+frandom()*256.0f);
temp_system.new_particle(p, v, 0.5f+0.5f*frandom(), 16.0f, 128.0f, 0.985f);
}
}
else if(item.type == EVENT_SPAWN)
else if(item.type == EVENT_PLAYERSPAWN)
{
ev_explosion *ev = (ev_explosion *)data;
vec2 p(ev->x, ev->y);
// center explosion
vec2 v = normalize(vec2(frandom()-0.5f, -frandom()))*(32.0f+frandom()*32.0f);
temp_system.new_particle(p, v, 1.2f, 64.0f, 0, 0.95f);
v = normalize(vec2(frandom()-0.5f, -frandom()))*(128.0f+frandom()*128.0f);
temp_system.new_particle(p, v, 1.2f, 32.0f, 0, 0.95f);
v = normalize(vec2(frandom()-0.5f, -frandom()))*(128.0f+frandom()*128.0f);
temp_system.new_particle(p, v, 1.2f, 16.0f, 0, 0.95f);
for(int i = 0; i < 8; i++)
{
vec2 v = normalize(vec2(frandom()-0.5f, frandom()-0.5f))*(64.0f+frandom()*64.0f);
temp_system.new_particle(p, v, 0.5f+0.5f*frandom(), 16.0f, 0, 0.985f);
}
for(int i = 0; i < 8; i++)
{
vec2 v = normalize(vec2(frandom()-0.5f, frandom()-0.5f))*(128.0f+frandom()*256.0f);
temp_system.new_particle(p, v, 0.5f+0.5f*frandom(), 16.0f, 128.0f, 0.985f);
}
effect_playerspawn(vec2(ev->x, ev->y));
}
else if(item.type == EVENT_DEATH)
{
ev_explosion *ev = (ev_explosion *)data;
vec2 p(ev->x, ev->y);
vec4 c(0.5f, 0.1f, 0.1f, 1.0f);
// center explosion
vec2 v = normalize(vec2(frandom()-0.5f, -frandom()))*(32.0f+frandom()*32.0f);
temp_system.new_particle(p, v, 1.2f, 64.0f, 0, 0.95f, c);
v = normalize(vec2(frandom()-0.5f, -frandom()))*(128.0f+frandom()*128.0f);
temp_system.new_particle(p, v, 1.2f, 32.0f, 0, 0.95f, c);
v = normalize(vec2(frandom()-0.5f, -frandom()))*(128.0f+frandom()*128.0f);
temp_system.new_particle(p, v, 1.2f, 16.0f, 0, 0.95f, c);
for(int i = 0; i < 8; i++)
{
vec2 v = normalize(vec2(frandom()-0.5f, frandom()-0.5f))*(64.0f+frandom()*64.0f);
temp_system.new_particle(p, v, 0.5f+0.5f*frandom(), 16.0f, 0, 0.985f, c);
}
for(int i = 0; i < 8; i++)
{
vec2 v = normalize(vec2(frandom()-0.5f, frandom()-0.5f))*(128.0f+frandom()*256.0f);
temp_system.new_particle(p, v, 0.5f+0.5f*frandom(), 16.0f, 128.0f, 0.985f, c);
}
effect_playerdeath(vec2(ev->x, ev->y));
}
else if(item.type == EVENT_SOUND_WORLD)
{
@ -964,6 +729,11 @@ static int do_input(int *v, int key)
void render_game()
{
// update the effects
effects_update();
particle_update(client_frametime());
float width = 400*3.0f*gfx_screenaspect();
float height = 400*3.0f;
@ -1195,12 +965,16 @@ void render_game()
}
// render the world
float zoom = 1.0f;
if(inp_key_pressed('E'))
zoom = 0.5f;
gfx_clear(0.65f,0.78f,0.9f);
if(spectate)
render_world(mouse_pos.x, mouse_pos.y, 1.0f);
render_world(mouse_pos.x, mouse_pos.y, zoom);
else
{
render_world(local_character_pos.x+offx, local_character_pos.y+offy, 1.0f);
render_world(local_character_pos.x+offx, local_character_pos.y+offy, zoom);
// draw screen box
if(0)
@ -1683,7 +1457,7 @@ void render_game()
vec2(local_character->x, local_character->y));
char buf[512];
sprintf(buf, "%.2f", speed);
sprintf(buf, "%.2f", speed/2);
gfx_text(0, 150, 50, 12, buf, -1);
}

View file

@ -83,12 +83,89 @@ const int killmsg_max = 5;
extern killmsg killmsgs[killmsg_max];
extern int killmsg_current;
//
void send_switch_team(int team);
// various helpers
void snd_play_random(int chn, int setid, float vol, vec2 pos);
void process_events(int snaptype);
void clear_object_pointers();
void reset_projectile_particles();
void send_info(bool start);
inline vec2 random_dir() { return normalize(vec2(frandom()-0.5f, frandom()-0.5f)); }
// effects
void effects_update();
void effect_bullettrail(vec2 pos);
void effect_smoketrail(vec2 pos, vec2 vel);
void effect_explosion(vec2 pos);
void effect_air_jump(vec2 pos);
void effect_damage_indicator(vec2 pos, vec2 dir);
void effect_playerspawn(vec2 pos);
void effect_playerdeath(vec2 pos);
// particles
struct particle
{
void set_default()
{
vel = vec2(0,0);
life_span = 0;
start_size = 32;
end_size = 32;
rot = 0;
rotspeed = 0;
gravity = 0;
friction = 0;
flow_affected = 1.0f;
color = vec4(1,1,1,1);
}
vec2 pos;
vec2 vel;
int spr;
float flow_affected;
float life_span;
float start_size;
float end_size;
float rot;
float rotspeed;
float gravity;
float friction;
vec4 color;
// set by the particle system
float life;
int prev_part;
int next_part;
};
enum
{
PARTGROUP_PROJECTILE_TRAIL=0,
PARTGROUP_EXPLOSIONS,
PARTGROUP_GENERAL,
NUM_PARTGROUPS
};
void particle_add(int group, particle *part);
void particle_render(int group);
void particle_update(float time_passed);
void particle_reset();
// flow grid
vec2 flow_get(vec2 pos);
void flow_add(vec2 pos, vec2 vel, float size);
void flow_dbg_render();
void flow_init();
void flow_update();

View file

@ -12,6 +12,7 @@ extern "C" {
#include <cstdio>
#include "gc_ui.h"
#include "gc_client.h"
static unsigned int console_input_len = 0;
static char console_input[256] = {0};
@ -57,12 +58,20 @@ static void quit_command(struct lexer_result *result, void *user_data)
client_quit();
}
static void con_team(struct lexer_result *result, void *user_data)
{
int new_team;
extract_result_int(result, 1, &new_team);
send_switch_team(new_team);
}
void client_console_init()
{
console_register_print_callback(client_console_print);
MACRO_REGISTER_COMMAND("quit", "", quit_command, 0x0);
MACRO_REGISTER_COMMAND("connect", "s", connect_command, 0x0);
MACRO_REGISTER_COMMAND("disconnect", "", disconnect_command, 0x0);
MACRO_REGISTER_COMMAND("team", "i", con_team, 0x0);
}
void console_handle_input()

View file

@ -0,0 +1,162 @@
#include <engine/e_client_interface.h>
#include "gc_client.h"
#include "../generated/gc_data.h"
static bool add_trail = false;
void effect_air_jump(vec2 pos)
{
particle p;
p.set_default();
p.spr = SPRITE_PART_AIRJUMP;
p.pos = pos + vec2(-6.0f, 16.0f);
p.vel = vec2(0, -200);
p.life_span = 0.5f;
p.start_size = 48.0f;
p.end_size = 0;
p.rot = frandom()*pi*2;
p.rotspeed = pi*2;
p.gravity = 500;
p.friction = 0.7f;
p.flow_affected = 0.0f;
particle_add(PARTGROUP_GENERAL, &p);
p.pos = pos + vec2(6.0f, 16.0f);
particle_add(PARTGROUP_GENERAL, &p);
}
void effect_smoketrail(vec2 pos, vec2 vel)
{
if(!add_trail)
return;
particle p;
p.set_default();
p.spr = SPRITE_PART_SMOKE;
p.pos = pos;
p.vel = vel + random_dir()*50.0f;
p.life_span = 0.5f + frandom()*0.5f;
p.start_size = 12.0f + frandom()*8;
p.end_size = 0;
p.friction = 0.7;
p.gravity = frandom()*-500.0f;
particle_add(PARTGROUP_PROJECTILE_TRAIL, &p);
}
void effect_bullettrail(vec2 pos)
{
if(!add_trail)
return;
particle p;
p.set_default();
p.spr = SPRITE_PART_BALL;
p.pos = pos;
p.life_span = 0.25f + frandom()*0.25f;
p.start_size = 8.0f;
p.end_size = 0;
p.friction = 0.7;
particle_add(PARTGROUP_PROJECTILE_TRAIL, &p);
}
void effect_playerspawn(vec2 pos)
{
for(int i = 0; i < 32; i++)
{
particle p;
p.set_default();
p.spr = SPRITE_PART_SHELL;
p.pos = pos;
p.vel = random_dir() * (pow(frandom(), 3)*600.0f);
p.life_span = 0.3f + frandom()*0.3f;
p.start_size = 64.0f + frandom()*32;
p.end_size = 0;
p.rot = frandom()*pi*2;
p.rotspeed = frandom();
p.gravity = frandom()*-400.0f;
p.friction = 0.7f;
p.color = vec4(0xb5/255.0f, 0x50/255.0f, 0xcb/255.0f, 1.0f);
particle_add(PARTGROUP_GENERAL, &p);
}
}
void effect_playerdeath(vec2 pos)
{
for(int i = 0; i < 64; i++)
{
particle p;
p.set_default();
p.spr = SPRITE_PART_SPLAT01 + (rand()%3);
p.pos = pos;
p.vel = random_dir() * ((frandom()+0.1f)*900.0f);
p.life_span = 0.3f + frandom()*0.3f;
p.start_size = 24.0f + frandom()*16;
p.end_size = 0;
p.rot = frandom()*pi*2;
p.rotspeed = (frandom()-0.5f) * pi;
p.gravity = 800.0f;
p.friction = 0.8f;
p.color = mix(vec4(0.75f,0.2f,0.2f,0.75f), vec4(0.5f,0.1f,0.1f,0.75f), frandom());
particle_add(PARTGROUP_GENERAL, &p);
}
}
void effect_explosion(vec2 pos)
{
// add to flow
for(int y = -8; y <= 8; y++)
for(int x = -8; x <= 8; x++)
{
if(x == 0 && y == 0)
continue;
float a = 1 - (length(vec2(x,y)) / length(vec2(8,8)));
flow_add(pos+vec2(x,y)*16, normalize(vec2(x,y))*5000.0f*a, 10.0f);
}
// add the explosion
particle p;
p.set_default();
p.spr = SPRITE_PART_EXPL01;
p.pos = pos;
p.life_span = 0.4f;
p.start_size = 150.0f;
p.end_size = 0;
p.rot = frandom()*pi*2;
particle_add(PARTGROUP_EXPLOSIONS, &p);
// add the smoke
for(int i = 0; i < 24; i++)
{
particle p;
p.set_default();
p.spr = SPRITE_PART_SMOKE;
p.pos = pos;
p.vel = random_dir() * ((1.0f + frandom()*0.2f) * 1000.0f);
p.life_span = 0.5f + frandom()*0.4f;
p.start_size = 32.0f + frandom()*8;
p.end_size = 0;
p.gravity = frandom()*-800.0f;
p.friction = 0.4f;
p.color = mix(vec4(0.75f,0.75f,0.75f,1.0f), vec4(0.5f,0.5f,0.5f,1.0f), frandom());
particle_add(PARTGROUP_GENERAL, &p);
}
}
void effects_update()
{
static float last_update = 0;
if(client_localtime()-last_update > 0.02f)
{
add_trail = true;
last_update = client_localtime();
flow_update();
}
else
add_trail = false;
}

View file

@ -0,0 +1,87 @@
#include <engine/e_client_interface.h>
#include <engine/e_config.h>
#include "gc_client.h"
#include "../g_layers.h"
struct FLOWCELL
{
vec2 vel;
};
static FLOWCELL *cells = 0;
static int height = 0;
static int width = 0;
static int spacing = 16;
void flow_init()
{
if(cells)
{
mem_free(cells);
cells = 0;
}
MAPITEM_LAYER_TILEMAP *tilemap = layers_game_layer();
width = tilemap->width*32/spacing;
height = tilemap->height*32/spacing;
// allocate and clear
cells = (FLOWCELL *)mem_alloc(sizeof(FLOWCELL)*width*height, 1);
for(int y = 0; y < height; y++)
for(int x = 0; x < width; x++)
cells[y*width+x].vel = vec2(0.0f, 0.0f);
}
void flow_update()
{
if(!config.cl_flow)
return;
for(int y = 0; y < height; y++)
for(int x = 0; x < width; x++)
cells[y*width+x].vel *= 0.85f;
}
void flow_dbg_render()
{
if(!config.cl_flow)
return;
gfx_texture_set(-1);
gfx_lines_begin();
for(int y = 0; y < height; y++)
for(int x = 0; x < width; x++)
{
vec2 pos(x*spacing, y*spacing);
vec2 vel = cells[y*width+x].vel * 0.01f;
gfx_lines_draw(pos.x, pos.y, pos.x+vel.x, pos.y+vel.y);
}
gfx_lines_end();
}
void flow_add(vec2 pos, vec2 vel, float size)
{
if(!config.cl_flow)
return;
int x = (int)(pos.x / spacing);
int y = (int)(pos.y / spacing);
if(x < 0 || y < 0 || x >= width || y >= height)
return;
cells[y*width+x].vel += vel;
}
vec2 flow_get(vec2 pos)
{
if(!config.cl_flow)
return vec2(0,0);
int x = (int)(pos.x / spacing);
int y = (int)(pos.y / spacing);
if(x < 0 || y < 0 || x >= width || y >= height)
return vec2(0,0);
return cells[y*width+x].vel;
}

View file

@ -40,6 +40,7 @@ extern "C" void modc_init()
gfx_text_set_default_font(&default_font);
particle_reset();
menu_init();
// setup sound channels
@ -300,13 +301,11 @@ extern "C" void modc_render()
// handle team switching
// TODO: FUGLY!!!
/*
if(config.cl_team != -10)
{
msg_pack_start(MSG_SETTEAM, MSGFLAG_VITAL);
msg_pack_int(config.cl_team);
msg_pack_end();
client_send_msg();
}
}*/
}
else // if (client_state() != CLIENTSTATE_CONNECTING && client_state() != CLIENTSTATE_LOADING)
{
@ -317,7 +316,7 @@ extern "C" void modc_render()
}
//
config.cl_team = -10;
//config.cl_team = -10;
}
@ -492,11 +491,12 @@ extern "C" void modc_connected()
layers_init();
col_init();
img_init();
flow_init();
//tilemap_init();
chat_reset();
reset_projectile_particles();
particle_reset();
clear_object_pointers();
last_new_predicted_tick = -1;

View file

@ -22,6 +22,7 @@ extern "C" {
#include "gc_anim.h"
#include "gc_skin.h"
#include "gc_ui.h"
#include "gc_client.h"
#include <mastersrv/mastersrv.h>
extern data_container *data;
@ -1623,7 +1624,7 @@ static void menu2_render_game(RECT main_view)
static int spectate_button = 0;
if(ui_do_button(&spectate_button, "Spectate", 0, &button, ui_draw_menu_button, 0))
{
config.cl_team = -1;
send_switch_team(-1);
menu_active = false;
}
}
@ -1637,7 +1638,7 @@ static void menu2_render_game(RECT main_view)
static int spectate_button = 0;
if(ui_do_button(&spectate_button, "Join Game", 0, &button, ui_draw_menu_button, 0))
{
config.cl_team = 0;
send_switch_team(0);
menu_active = false;
}
}
@ -1651,7 +1652,7 @@ static void menu2_render_game(RECT main_view)
static int spectate_button = 0;
if(ui_do_button(&spectate_button, "Join Red", 0, &button, ui_draw_menu_button, 0))
{
config.cl_team = 0;
send_switch_team(0);
menu_active = false;
}
}
@ -1663,7 +1664,7 @@ static void menu2_render_game(RECT main_view)
static int spectate_button = 0;
if(ui_do_button(&spectate_button, "Join Blue", 0, &button, ui_draw_menu_button, 0))
{
config.cl_team = 1;
send_switch_team(1);
menu_active = false;
}
}

View file

@ -0,0 +1,146 @@
#include <engine/e_client_interface.h>
#include "gc_client.h"
#include "../generated/gc_data.h"
// NOTE: the way the particle system works isn't very cache friendly
enum
{
MAX_PARTICLES=1024*8,
};
static particle particles[MAX_PARTICLES];
static int first_free = -1;
static int first_part[NUM_PARTGROUPS] = {-1};
void particle_reset()
{
// reset particles
for(int i = 0; i < MAX_PARTICLES; i++)
{
particles[i].prev_part = i-1;
particles[i].next_part = i+1;
}
particles[0].prev_part = 0;
particles[MAX_PARTICLES-1].next_part = -1;
first_free = 0;
for(int i = 0; i < NUM_PARTGROUPS; i++)
first_part[i] = -1;
}
void particle_add(int group, particle *part)
{
if (first_free == -1)
return;
// remove from the free list
int id = first_free;
first_free = particles[id].next_part;
particles[first_free].prev_part = -1;
// copy data
particles[id] = *part;
// insert to the group list
particles[id].prev_part = -1;
particles[id].next_part = first_part[group];
if(first_part[group] != -1)
particles[first_part[group]].prev_part = id;
first_part[group] = id;
// set some parameters
particles[id].life = 0;
}
void particle_update(float time_passed)
{
static float friction_fraction = 0;
friction_fraction += time_passed;
if(friction_fraction > 2.0f) // safty messure
friction_fraction = 0;
int friction_count = 0;
while(friction_fraction > 0.05f)
{
friction_count++;
friction_fraction -= 0.05f;
}
for(int g = 0; g < NUM_PARTGROUPS; g++)
{
int i = first_part[g];
while(i != -1)
{
int next = particles[i].next_part;
particles[i].vel += flow_get(particles[i].pos)*time_passed * particles[i].flow_affected;
particles[i].vel.y += particles[i].gravity*time_passed;
for(int f = 0; f < friction_count; f++) // apply friction
particles[i].vel *= particles[i].friction;
// move the point
vec2 vel = particles[i].vel*time_passed;
move_point(&particles[i].pos, &vel, 0.1f+0.9f*frandom(), NULL);
particles[i].vel = vel* (1.0f/time_passed);
particles[i].life += time_passed;
particles[i].rot += time_passed * particles[i].rotspeed;
// check particle death
if(particles[i].life > particles[i].life_span)
{
// remove it from the group list
if(particles[i].prev_part != -1)
particles[particles[i].prev_part].next_part = particles[i].next_part;
else
first_part[g] = particles[i].next_part;
if(particles[i].next_part != -1)
particles[particles[i].next_part].prev_part = particles[i].prev_part;
// insert to the free list
if(first_free != -1)
particles[first_free].prev_part = i;
particles[i].prev_part = -1;
particles[i].next_part = first_free;
}
i = next;
}
}
}
void particle_render(int group)
{
gfx_blend_normal();
//gfx_blend_additive();
gfx_texture_set(data->images[IMAGE_PARTICLES].id);
gfx_quads_begin();
int i = first_part[group];
while(i != -1)
{
select_sprite(particles[i].spr);
float a = particles[i].life / particles[i].life_span;
vec2 p = particles[i].pos;
float size = mix(particles[i].start_size, particles[i].end_size, a);
gfx_quads_setrotation(particles[i].rot);
gfx_setcolor(
particles[i].color.r,
particles[i].color.g,
particles[i].color.b,
particles[i].color.a); // pow(a, 0.75f) *
gfx_quads_draw(p.x, p.y, size, size);
i = particles[i].next_part;
}
gfx_quads_end();
gfx_blend_normal();
}

View file

@ -197,7 +197,7 @@ void render_tee(animstate *anim, tee_render_info *info, int emote, vec2 dir, vec
// draw feet
gfx_setcolor(info->color_feet.r, info->color_feet.g, info->color_feet.b, info->color_feet.a);
select_sprite(outline?SPRITE_TEE_FOOT_OUTLINE:SPRITE_TEE_FOOT, 0, 0, 0);
select_sprite((outline||!info->got_airjump)?SPRITE_TEE_FOOT_OUTLINE:SPRITE_TEE_FOOT, 0, 0, 0);
keyframe *foot = f ? &anim->front_foot : &anim->back_foot;
@ -278,7 +278,7 @@ void render_layers(float center_x, float center_y, int pass)
bool render = false;
bool is_game_layer = false;
if(layer == (MAPITEM_LAYER*)layers_game())
if(layer == (MAPITEM_LAYER*)layers_game_layer())
{
is_game_layer = true;
passed_gamelayer = 1;
@ -306,7 +306,7 @@ void render_layers(float center_x, float center_y, int pass)
else
gfx_texture_set(img_get(tmap->image));
TILE *tiles = (TILE *)map_get_data(tmap->data);
render_tilemap(tiles, tmap->width, tmap->height, 32.0f, 1);
render_tilemap(tiles, tmap->width, tmap->height, 32.0f, vec4(1,1,1,1), 1);
}
else if(layer->type == LAYERTYPE_QUADS)
{
@ -323,71 +323,82 @@ void render_layers(float center_x, float center_y, int pass)
}
}
static void render_items()
{
int num = snap_num_items(SNAP_CURRENT);
for(int i = 0; i < num; i++)
{
SNAP_ITEM item;
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
if(item.type == OBJTYPE_PROJECTILE)
{
render_projectile((const obj_projectile *)data, item.id);
}
else if(item.type == OBJTYPE_POWERUP)
{
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
if(prev)
render_powerup((const obj_powerup *)prev, (const obj_powerup *)data);
}
else if(item.type == OBJTYPE_FLAG)
{
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
if (prev)
render_flag((const obj_flag *)prev, (const obj_flag *)data);
}
}
}
static void render_players()
{
int num = snap_num_items(SNAP_CURRENT);
for(int i = 0; i < num; i++)
{
SNAP_ITEM item;
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
if(item.type == OBJTYPE_PLAYER_CHARACTER)
{
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
const void *prev_info = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_INFO, item.id);
const void *info = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_INFO, item.id);
if(prev && prev_info && info)
{
render_player(
(const obj_player_character *)prev,
(const obj_player_character *)data,
(const obj_player_info *)prev_info,
(const obj_player_info *)info
);
}
}
}
}
// renders the complete game world
void render_world(float center_x, float center_y, float zoom)
{
// render background layers
render_layers(center_x, center_y, 0);
// render items
{
int num = snap_num_items(SNAP_CURRENT);
for(int i = 0; i < num; i++)
{
SNAP_ITEM item;
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
// render trails
particle_render(PARTGROUP_PROJECTILE_TRAIL);
if(item.type == OBJTYPE_PROJECTILE)
{
//const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
//if(prev)
render_projectile((const obj_projectile *)data, item.id);
}
else if(item.type == OBJTYPE_POWERUP)
{
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
if(prev)
render_powerup((const obj_powerup *)prev, (const obj_powerup *)data);
}
else if(item.type == OBJTYPE_FLAG)
{
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
if (prev)
render_flag((const obj_flag *)prev, (const obj_flag *)data);
}
}
}
// render items
render_items();
// render players above all
{
int num = snap_num_items(SNAP_CURRENT);
for(int i = 0; i < num; i++)
{
SNAP_ITEM item;
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
if(item.type == OBJTYPE_PLAYER_CHARACTER)
{
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
const void *prev_info = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_INFO, item.id);
const void *info = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_INFO, item.id);
if(prev && prev_info && info)
{
render_player(
(const obj_player_character *)prev,
(const obj_player_character *)data,
(const obj_player_info *)prev_info,
(const obj_player_info *)info
);
}
}
}
}
render_players();
// render particles
//temp_system.update(client_frametime());
//temp_system.render();
particle_render(PARTGROUP_EXPLOSIONS);
particle_render(PARTGROUP_GENERAL);
if(config.dbg_flow)
flow_dbg_render();
// render foreground layers
render_layers(center_x, center_y, 1);

View file

@ -8,10 +8,20 @@
struct tee_render_info
{
tee_render_info()
{
texture = -1;
color_body = vec4(1,1,1,1);
color_feet = vec4(1,1,1,1);
size = 1.0f;
got_airjump = 1;
};
int texture;
vec4 color_body;
vec4 color_feet;
float size;
int got_airjump;
};
// sprite renderings
@ -40,6 +50,7 @@ void render_world(float center_x, float center_y, float zoom);
void render_loading(float percent);
void render_damage_indicators();
void render_particles();
// object render methods (gc_render_obj.cpp)
void render_tee(class animstate *anim, tee_render_info *info, int emote, vec2 dir, vec2 pos);
@ -53,7 +64,7 @@ void render_player(
// map render methods (gc_render_map.cpp)
void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result);
void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, int env, float *channels));
void render_tilemap(TILE *tiles, int w, int h, float scale, int flags);
void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int flags);
// helpers
void mapscreen_to_world(float center_x, float center_y, float parallax_x, float parallax_y,

View file

@ -148,7 +148,7 @@ void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, in
}
void render_tilemap(TILE *tiles, int w, int h, float scale, int flags)
void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int flags)
{
//gfx_texture_set(img_get(tmap->image));
float screen_x0, screen_y0, screen_x1, screen_y1;
@ -160,6 +160,7 @@ void render_tilemap(TILE *tiles, int w, int h, float scale, int flags)
float final_tilesize_scale = final_tilesize/tile_pixelsize;
gfx_quads_begin();
gfx_setcolor(color.r, color.g, color.b, color.a);
int starty = (int)(screen_y0/scale)-1;
int startx = (int)(screen_x0/scale)-1;

View file

@ -1,5 +1,6 @@
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
#include <math.h>
#include <stdio.h>
#include <engine/e_client_interface.h>
#include <engine/e_config.h>
#include "../generated/gc_data.h"
@ -27,8 +28,6 @@ void render_projectile(const obj_projectile *current, int itemid)
float gravity = -400;
if(current->type != WEAPON_ROCKET)
gravity = -100;
if(current->type == WEAPON_BOMB)
gravity = 0;
float ct = (client_tick()-current->start_tick)/(float)SERVER_TICK_SPEED + client_ticktime()*1/(float)SERVER_TICK_SPEED;
vec2 startpos(current->x, current->y);
@ -39,17 +38,26 @@ void render_projectile(const obj_projectile *current, int itemid)
select_sprite(data->weapons[current->type%data->num_weapons].sprite_proj);
vec2 vel = pos-prevpos;
//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
// add particle for this projectile
//proj_particles.addparticle(current->type, itemid, pos, vel);
if(length(vel) > 0.00001f)
gfx_quads_setrotation(get_angle(vel));
if(current->type == WEAPON_ROCKET)
{
effect_smoketrail(pos, vel*-1);
flow_add(pos, vel*1000*client_frametime(), 10.0f);
gfx_quads_setrotation(client_localtime()*pi*2*2 + itemid);
}
else
gfx_quads_setrotation(0);
{
effect_bullettrail(pos);
flow_add(pos, vel*1000*client_frametime(), 10.0f);
// TODO: do this, but nice
//temp_system.new_particle(pos, vec2(0,0), 0.3f, 14.0f, 0, 0.95f);
if(length(vel) > 0.00001f)
gfx_quads_setrotation(get_angle(vel));
else
gfx_quads_setrotation(0);
}
gfx_quads_draw(pos.x, pos.y, 32, 32);
gfx_quads_setrotation(0);
@ -185,6 +193,7 @@ void render_player(
player = *player_char;
obj_player_info info = *player_info;
tee_render_info render_info = client_datas[info.clientid].render_info;
float intratick = client_intratick();
float ticktime = client_ticktime();
@ -209,6 +218,11 @@ void render_player(
vec2 direction = get_direction(player.angle);
float angle = player.angle/256.0f;
vec2 position = mix(vec2(prev.x, prev.y), vec2(player.x, player.y), intratick);
vec2 vel = vec2(player.x, player.y)-vec2(prev.x, prev.y);
flow_add(position, vel*100.0f, 10.0f);
render_info.got_airjump = player.jumped&2?0:1;
if(prev.health < 0) // Don't flicker from previous position
position = vec2(player.x, player.y);
@ -411,14 +425,14 @@ void render_player(
if(info.local && config.debug)
{
vec2 ghost_position = mix(vec2(prev_char->x, prev_char->y), vec2(player_char->x, player_char->y), client_intratick());
tee_render_info ghost = client_datas[info.clientid].render_info;
tee_render_info ghost = render_info;
ghost.color_body.a = 0.5f;
ghost.color_feet.a = 0.5f;
render_tee(&state, &ghost, player.emote, direction, ghost_position); // render ghost
}
// render the tee
render_tee(&state, &client_datas[info.clientid].render_info, player.emote, direction, position);
render_tee(&state, &render_info, player.emote, direction, position);
if(player.state == STATE_CHATTING)
{

View file

@ -221,6 +221,11 @@ public:
format = 0;
}
~IMAGE()
{
gfx_unload_texture(tex_id);
}
int tex_id;
int external;
char name[128];

View file

@ -34,7 +34,7 @@ void LAYER_TILES::render()
if(image >= 0 && image < editor.map.images.len())
tex_id = editor.map.images[image]->tex_id;
gfx_texture_set(tex_id);
render_tilemap(tiles, width, height, 32.0f, 0);
render_tilemap(tiles, width, height, 32.0f, vec4(1,1,1,1), 0);
}
int LAYER_TILES::convert_x(float x) const { return (int)(x/32.0f); }

View file

@ -16,9 +16,9 @@ int col_height() { return height; }
int col_init()
{
width = layers_game()->width;
height = layers_game()->height;
tiles = (TILE *)map_get_data(layers_game()->data);
width = layers_game_layer()->width;
height = layers_game_layer()->height;
tiles = (TILE *)map_get_data(layers_game_layer()->data);
return 1;
}

View file

@ -284,7 +284,7 @@ void player_core::tick()
hookvel.x *= 0.75f;
vec2 new_vel = vel+hookvel;
// check if we are under the legal limit for the hook
if(length(new_vel) < hook_drag_speed || length(new_vel) < length(vel))
vel = new_vel; // no problem. apply
@ -348,8 +348,8 @@ void player_core::tick()
}
// clamp the velocity to something sane
if(length(vel) > 100.0f)
vel = normalize(vel) * 100.0f;
if(length(vel) > terminal_velocity)
vel = normalize(vel) * terminal_velocity;
}
void player_core::move()

View file

@ -1,7 +1,8 @@
#include <engine/e_common_interface.h>
#include "g_layers.h"
static MAPITEM_LAYER_TILEMAP *game_layer;
static MAPITEM_LAYER_TILEMAP *game_layer = 0;
static MAPITEM_GROUP *game_group = 0;
static int groups_start = 0;
static int groups_num = 0;
@ -13,6 +14,7 @@ void layers_init()
map_get_type(MAPITEMTYPE_GROUP, &groups_start, &groups_num);
{
int p = 0;
map_get_type(MAPITEMTYPE_LAYER, &layers_start, &layers_num);
for(int i = 0; i < layers_num; i++)
@ -21,11 +23,23 @@ void layers_init()
if(layer->type == LAYERTYPE_TILES)
{
MAPITEM_LAYER_TILEMAP *tilemap = (MAPITEM_LAYER_TILEMAP *)layer;
if(p)
{
p--;
if(p == 0)
tilemap->flags |= 2;
}
if(tilemap->flags&1)
{
dbg_msg("layers", "game");
game_layer = tilemap;
p = 2;
}
}
dbg_msg("layers", "%d %d", i, layer->type);
}
}
}
@ -40,8 +54,13 @@ MAPITEM_LAYER *layers_get_layer(int index)
return (MAPITEM_LAYER *)map_get_item(layers_start+index, 0, 0);
}
MAPITEM_LAYER_TILEMAP *layers_game()
MAPITEM_LAYER_TILEMAP *layers_game_layer()
{
return game_layer;
}
MAPITEM_GROUP *layers_game_group()
{
return game_group;
}

View file

@ -2,7 +2,8 @@
void layers_init();
MAPITEM_LAYER_TILEMAP *layers_game();
MAPITEM_LAYER_TILEMAP *layers_game_layer();
MAPITEM_GROUP *layers_game_group();
int layers_num_groups();
MAPITEM_GROUP *layers_get_group(int index);

View file

@ -5,12 +5,13 @@
#define GAME_PROTOCOL_H
// --------- PHYSICS TWEAK! --------
const float ground_control_speed = 7.0f;
const float ground_control_accel = 2.0f;
const float ticks_per_second = 50.0f;
const float ground_control_speed = 350.0f / ticks_per_second;
const float ground_control_accel = 100.0f / ticks_per_second;
const float ground_friction = 0.5f;
const float ground_jump_speed = 12.6f;
const float ground_air_speed = 11.5f;
const float air_control_speed = 5.0f;
const float air_control_speed = 250.0f / ticks_per_second;
const float air_control_accel = 1.5f;
const float air_friction = 0.95f;
const float hook_length = 34*10.0f;
@ -18,6 +19,8 @@ const float hook_fire_speed = 45.0f;
const float hook_drag_accel = 3.0f;
const float hook_drag_speed = 15.0f;
const float gravity = 0.5f;
const float terminal_velocity = 20.0f;
const float wall_friction = 0.80f;
const float wall_jump_speed_up = ground_jump_speed*0.8f;
const float wall_jump_speed_out = ground_jump_speed*0.8f;
@ -36,7 +39,7 @@ enum
EVENT_DAMAGEINDICATION,
EVENT_SOUND_WORLD,
EVENT_SMOKE,
EVENT_SPAWN,
EVENT_PLAYERSPAWN,
EVENT_DEATH,
EVENT_AIR_JUMP,

View file

@ -25,16 +25,17 @@ MACRO_CONFIG_INT(key_remoteconsole, 256+3, 32, 512)
MACRO_CONFIG_INT(key_toggleconsole, 256+4, 32, 512)
MACRO_CONFIG_INT(dbg_bots, 0, 0, 11)
MACRO_CONFIG_INT(cl_predict, 1, 0, 1)
MACRO_CONFIG_INT(cl_nameplates, 0, 0, 1)
MACRO_CONFIG_INT(cl_nameplates_always, 0, 0, 1)
MACRO_CONFIG_INT(cl_dynamic_camera, 1, 0, 1)
MACRO_CONFIG_INT(cl_team, -10, -1, 0)
MACRO_CONFIG_INT(cl_autoswitch_weapons, 0, 0, 1)
MACRO_CONFIG_INT(cl_show_player_ids, 0, 0, 1)
MACRO_CONFIG_INT(cl_flow, 0, 0, 1)
MACRO_CONFIG_INT(cl_show_welcome, 1, 0, 1)
MACRO_CONFIG_INT(player_use_custom_color, 0, 0, 1)
@ -42,7 +43,9 @@ MACRO_CONFIG_INT(player_color_body, 65408, 0, 0)
MACRO_CONFIG_INT(player_color_feet, 65408, 0, 0)
MACRO_CONFIG_STR(player_skin, 64, "default")
MACRO_CONFIG_INT(dbg_bots, 0, 0, 11)
MACRO_CONFIG_INT(dbg_firedelay, 0, 0, 1)
MACRO_CONFIG_INT(dbg_flow, 0, 0, 1)
MACRO_CONFIG_INT(ui_page, 1, 0, 5)
MACRO_CONFIG_STR(ui_server_address, 128, "localhost:8303")

View file

@ -248,8 +248,6 @@ public:
int attack_tick;
int sniper_chargetick;
int bomb_firetick;
int damage_taken;

View file

@ -18,7 +18,7 @@ class player* get_player(int index);
void create_damageind(vec2 p, float angle_mod, int amount);
void create_explosion(vec2 p, int owner, int weapon, bool bnodamage);
void create_smoke(vec2 p);
void create_spawn(vec2 p);
void create_playerspawn(vec2 p);
void create_death(vec2 p);
void create_sound(vec2 pos, int sound, int mask=-1);
class player *intersect_player(vec2 pos0, vec2 pos1, vec2 &new_pos, class entity *notthis = 0);
@ -396,8 +396,6 @@ void projectile::tick()
float gravity = -400;
if(type != WEAPON_ROCKET)
gravity = -100;
if(type == WEAPON_BOMB)
gravity = 0;
float pt = (server_tick()-start_tick-1)/(float)server_tickspeed();
float ct = (server_tick()-start_tick)/(float)server_tickspeed();
@ -410,17 +408,10 @@ void projectile::tick()
vec2 new_pos;
entity *targetplayer = (entity*)intersect_player(prevpos, curpos, new_pos, powner);
player *p = (player*) powner;
if(targetplayer || collide || lifespan < 0 || (type == WEAPON_BOMB && count_input(p->previnput.fire, p->input.fire).releases))
if(targetplayer || collide || lifespan < 0)
{
if(type == WEAPON_BOMB)
{
p->bomb_firetick = -1;
p->reload_timer = data->weapons[WEAPON_BOMB].firedelay * server_tickspeed() / 1000;
}
if (lifespan >= 0 || weapon == WEAPON_ROCKET || weapon == WEAPON_BOMB)
if (lifespan >= 0 || weapon == WEAPON_ROCKET)
create_sound(pos, sound_impact);
if (flags & PROJECTILE_FLAGS_EXPLODE)
@ -504,7 +495,6 @@ void player::reset()
numobjectshit = 0;
ninja_activationtick = 0;
sniper_chargetick = -1;
bomb_firetick = -1;
currentmovetime = 0;
active_weapon = WEAPON_GUN;
@ -718,8 +708,6 @@ void player::try_respawn()
//weapons[WEAPON_SNIPER].got = true;
//weapons[WEAPON_SNIPER].ammo = data->weapons[WEAPON_SNIPER].maxammo;
weapons[WEAPON_BOMB].got = true;
weapons[WEAPON_BOMB].ammo = data->weapons[WEAPON_BOMB].maxammo;
active_weapon = WEAPON_GUN;
last_weapon = WEAPON_HAMMER;
wanted_weapon = WEAPON_GUN;
@ -728,7 +716,7 @@ void player::try_respawn()
// Create sound and spawn effects
create_sound(pos, SOUND_PLAYER_SPAWN);
create_spawn(pos);
create_playerspawn(pos);
gameobj->on_player_spawn(this);
}
@ -941,32 +929,6 @@ int player::handle_sniper()
return 0;
}
int player::handle_bomb()
{
struct input_count button = count_input(previnput.fire, input.fire);
if(button.releases)
{
}
else if(input.fire & 1 && bomb_firetick == -1 && reload_timer == 0)
{
vec2 direction = normalize(vec2(input.target_x, input.target_y));
new projectile(WEAPON_BOMB,
client_id,
pos+vec2(0,0),
direction*7.0f,
100,
this,
1, projectile::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_ROCKET_EXPLODE, WEAPON_ROCKET);
create_sound(pos, SOUND_ROCKET_FIRE);
bomb_firetick = server_tick();
attack_tick = server_tick();
weapons[active_weapon].ammo--;
}
return 0;
}
int player::handle_weapons()
{
vec2 direction = normalize(vec2(latest_input.target_x, latest_input.target_y));
@ -1043,8 +1005,6 @@ int player::handle_weapons()
if (active_weapon == WEAPON_SNIPER)
return handle_sniper();
*/
if (active_weapon == WEAPON_BOMB)
return handle_bomb();
if(reload_timer == 0)
{
@ -1073,7 +1033,7 @@ int player::handle_weapons()
client_id,
pos+vec2(0,0),
direction*30.0f,
100,
server_tickspeed(),
this,
1, 0, 0, -1, WEAPON_GUN);
create_sound(pos, SOUND_GUN_FIRE);
@ -1105,7 +1065,7 @@ int player::handle_weapons()
pos+vec2(0,0),
vec2(cosf(a), sinf(a))*(28.0f + 12.0f*v),
//vec2(cosf(a), sinf(a))*20.0f,
(int)(server_tickspeed()*0.3f),
(int)(server_tickspeed()*0.25f),
this,
1, 0, 0, -1, WEAPON_SHOTGUN);
}
@ -1723,12 +1683,6 @@ void create_explosion(vec2 p, int owner, int weapon, bool bnodamage)
float radius = 128.0f;
float innerradius = 42.0f;
if(weapon == WEAPON_BOMB)
{
radius = 256.0f;
innerradius = 64.0f;
}
int num = world->find_entities(p, radius, ents, 64);
for(int i = 0; i < num; i++)
{
@ -1756,10 +1710,10 @@ void create_smoke(vec2 p)
}
}
void create_spawn(vec2 p)
void create_playerspawn(vec2 p)
{
// create the event
ev_spawn *ev = (ev_spawn *)events.create(EVENT_SPAWN, sizeof(ev_spawn));
ev_spawn *ev = (ev_spawn *)events.create(EVENT_PLAYERSPAWN, sizeof(ev_spawn));
if(ev)
{
ev->x = (int)p.x;
@ -2062,7 +2016,7 @@ void mods_init()
players[i].core.world = &world->core;
// create all entities from the game layer
MAPITEM_LAYER_TILEMAP *tmap = layers_game();
MAPITEM_LAYER_TILEMAP *tmap = layers_game_layer();
TILE *tiles = (TILE *)map_get_data(tmap->data);
num_spawn_points[0] = 0;