mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
editor update and other stuff
This commit is contained in:
parent
253a5639ae
commit
57c4765993
File diff suppressed because it is too large
Load diff
|
@ -70,15 +70,6 @@ enum
|
|||
PAGE_SYSTEM,
|
||||
};
|
||||
|
||||
static void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding)
|
||||
{
|
||||
gfx_texture_set(-1);
|
||||
gfx_quads_begin();
|
||||
gfx_setcolor(color.r, color.g, color.b, color.a);
|
||||
draw_round_rect_ext(r->x,r->y,r->w,r->h,rounding*ui_scale(), corners);
|
||||
gfx_quads_end();
|
||||
}
|
||||
|
||||
static void ui_draw_browse_icon(int what, const RECT *r)
|
||||
{
|
||||
gfx_texture_set(data->images[IMAGE_BROWSEICONS].id);
|
||||
|
|
|
@ -1,16 +1,5 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef __MENU_H
|
||||
#define __MENU_H
|
||||
/*
|
||||
void draw_image_button(void *id, const char *text, int checked, float x, float y, float w, float h, void *extra);
|
||||
void draw_single_part_button(void *id, const char *text, int checked, float x, float y, float w, float h, void *extra);
|
||||
void draw_menu_button(void *id, const char *text, int checked, float x, float y, float w, float h, void *extra);
|
||||
void draw_teewars_button(void *id, const char *text, int checked, float x, float y, float w, float h, void *extra);
|
||||
int ui_do_key_reader(void *id, float x, float y, float w, float h, int key);
|
||||
int ui_do_combo_box(void *id, float x, float y, float w, char *lines, int line_count, int selected_index);
|
||||
int ui_do_edit_box(void *id, float x, float y, float w, float h, char *str, int str_size);
|
||||
int ui_do_check_box(void *id, float x, float y, float w, float h, int value);
|
||||
int do_scroll_bar_horiz(void *id, float x, float y, float width, int steps, int last_index);
|
||||
int do_scroll_bar_vert(void *id, float x, float y, float height, int steps, int last_index);
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
|
@ -125,6 +125,15 @@ void draw_round_rect(float x, float y, float w, float h, float r)
|
|||
draw_round_rect_ext(x,y,w,h,r,0xf);
|
||||
}
|
||||
|
||||
void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding)
|
||||
{
|
||||
gfx_texture_set(-1);
|
||||
gfx_quads_begin();
|
||||
gfx_setcolor(color.r, color.g, color.b, color.a);
|
||||
draw_round_rect_ext(r->x,r->y,r->w,r->h,rounding*ui_scale(), corners);
|
||||
gfx_quads_end();
|
||||
}
|
||||
|
||||
void render_tee(animstate *anim, tee_render_info *info, int emote, vec2 dir, vec2 pos)
|
||||
{
|
||||
vec2 direction = dir;
|
||||
|
@ -246,6 +255,14 @@ static void mapscreen_to_group(float center_x, float center_y, MAPITEM_GROUP *gr
|
|||
gfx_mapscreen(points[0], points[1], points[2], points[3]);
|
||||
}
|
||||
|
||||
static void envelope_eval(float time_offset, int env, float *channels)
|
||||
{
|
||||
channels[0] = 0;
|
||||
channels[1] = 0;
|
||||
channels[2] = 0;
|
||||
channels[3] = 0;
|
||||
}
|
||||
|
||||
void render_layers(float center_x, float center_y, int pass)
|
||||
{
|
||||
bool passed_gamelayer = false;
|
||||
|
@ -299,7 +316,7 @@ void render_layers(float center_x, float center_y, int pass)
|
|||
else
|
||||
gfx_texture_set(img_get(qlayer->image));
|
||||
QUAD *quads = (QUAD *)map_get_data_swapped(qlayer->data);
|
||||
render_quads(quads, qlayer->num_quads);
|
||||
render_quads(quads, qlayer->num_quads, envelope_eval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "../g_vmath.h"
|
||||
#include "../g_mapitems.h"
|
||||
#include "gc_ui.h"
|
||||
|
||||
struct tee_render_info
|
||||
{
|
||||
|
@ -30,6 +31,7 @@ void draw_sprite(float x, float y, float size);
|
|||
// rects
|
||||
void draw_round_rect(float x, float y, float w, float h, float r);
|
||||
void draw_round_rect_ext(float x, float y, float w, float h, float r, int corners);
|
||||
void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding);
|
||||
|
||||
// larger rendering methods
|
||||
void menu_render();
|
||||
|
@ -49,7 +51,8 @@ void render_player(
|
|||
const struct obj_player_info *prev_info, const struct obj_player_info *player_info);
|
||||
|
||||
// map render methods (gc_render_map.cpp)
|
||||
void render_quads(QUAD *quads, int num_quads);
|
||||
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);
|
||||
|
||||
// helpers
|
||||
|
|
|
@ -3,6 +3,70 @@
|
|||
#include "../g_math.h"
|
||||
#include "gc_client.h"
|
||||
|
||||
void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result)
|
||||
{
|
||||
if(num_points == 0)
|
||||
{
|
||||
result[0] = 0;
|
||||
result[1] = 0;
|
||||
result[2] = 0;
|
||||
result[3] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(num_points == 1)
|
||||
{
|
||||
result[0] = fx2f(points[0].values[0]);
|
||||
result[1] = fx2f(points[0].values[1]);
|
||||
result[2] = fx2f(points[0].values[2]);
|
||||
result[3] = fx2f(points[0].values[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
time = fmod(time, points[num_points-1].time/1000.0f)*1000.0f;
|
||||
for(int i = 0; i < num_points-1; i++)
|
||||
{
|
||||
if(time >= points[i].time && time <= points[i+1].time)
|
||||
{
|
||||
float delta = points[i+1].time-points[i].time;
|
||||
float a = (time-points[i].time)/delta;
|
||||
|
||||
|
||||
if(points[i].curvetype == CURVETYPE_SMOOTH)
|
||||
a = -2*a*a*a + 3*a*a; // second hermite basis
|
||||
else if(points[i].curvetype == CURVETYPE_SLOW)
|
||||
a = a*a*a;
|
||||
else if(points[i].curvetype == CURVETYPE_FAST)
|
||||
{
|
||||
a = 1-a;
|
||||
a = 1-a*a*a;
|
||||
}
|
||||
else if (points[i].curvetype == CURVETYPE_STEP)
|
||||
a = 0;
|
||||
else
|
||||
{
|
||||
// linear
|
||||
}
|
||||
|
||||
for(int c = 0; c < channels; c++)
|
||||
{
|
||||
float v0 = fx2f(points[i].values[c]);
|
||||
float v1 = fx2f(points[i+1].values[c]);
|
||||
result[c] = v0 + (v1-v0) * a;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
result[0] = fx2f(points[num_points-1].values[0]);
|
||||
result[1] = fx2f(points[num_points-1].values[1]);
|
||||
result[2] = fx2f(points[num_points-1].values[2]);
|
||||
result[3] = fx2f(points[num_points-1].values[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void rotate(POINT *center, POINT *point, float rotation)
|
||||
{
|
||||
int x = point->x - center->x;
|
||||
|
@ -11,7 +75,7 @@ static void rotate(POINT *center, POINT *point, float rotation)
|
|||
point->y = (int)(x * sinf(rotation) + y * cosf(rotation) + center->y);
|
||||
}
|
||||
|
||||
void render_quads(QUAD *quads, int num_quads)
|
||||
void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, int env, float *channels))
|
||||
{
|
||||
gfx_quads_begin();
|
||||
float conv = 1/255.0f;
|
||||
|
@ -31,29 +95,25 @@ void render_quads(QUAD *quads, int num_quads)
|
|||
float offset_y = 0;
|
||||
float rot = 0;
|
||||
|
||||
/*
|
||||
// TODO: fix this
|
||||
if(editor.animate)
|
||||
if(q->pos_env >= 0)
|
||||
{
|
||||
if(q->pos_env >= 0 && q->pos_env < editor.map.envelopes.len())
|
||||
{
|
||||
ENVELOPE *e = editor.map.envelopes[q->pos_env];
|
||||
float t = editor.animate_time+q->pos_env_offset/1000.0f;
|
||||
offset_x = e->eval(t, 0);
|
||||
offset_y = e->eval(t, 1);
|
||||
rot = e->eval(t, 2);
|
||||
}
|
||||
|
||||
if(q->color_env >= 0 && q->color_env < editor.map.envelopes.len())
|
||||
{
|
||||
ENVELOPE *e = editor.map.envelopes[q->color_env];
|
||||
float t = editor.animate_time+q->color_env_offset/1000.0f;
|
||||
r = e->eval(t, 0);
|
||||
g = e->eval(t, 1);
|
||||
b = e->eval(t, 2);
|
||||
a = e->eval(t, 3);
|
||||
}
|
||||
}*/
|
||||
float channels[4];
|
||||
eval(q->pos_env_offset/1000.0f, q->pos_env, channels);
|
||||
offset_x = channels[0];
|
||||
offset_y = channels[1];
|
||||
rot = channels[2];
|
||||
}
|
||||
|
||||
if(q->color_env >= 0)
|
||||
{
|
||||
float channels[4];
|
||||
eval(q->color_env_offset/1000.0f, q->color_env, channels);
|
||||
r = channels[0];
|
||||
g = channels[1];
|
||||
b = channels[2];
|
||||
a = channels[3];
|
||||
}
|
||||
|
||||
gfx_setcolorvertex(0, q->colors[0].r*conv*r, q->colors[0].g*conv*g, q->colors[0].b*conv*b, q->colors[0].a*conv*a);
|
||||
gfx_setcolorvertex(1, q->colors[1].r*conv*r, q->colors[1].g*conv*g, q->colors[1].b*conv*b, q->colors[1].a*conv*a);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,6 +4,7 @@
|
|||
#include <math.h>
|
||||
#include "array.h"
|
||||
#include "../g_mapitems.h"
|
||||
#include "../client/gc_render.h"
|
||||
|
||||
extern "C" {
|
||||
#include <engine/e_system.h>
|
||||
|
@ -32,30 +33,12 @@ enum
|
|||
DIALOG_FILE,
|
||||
};
|
||||
|
||||
typedef struct // as in file
|
||||
typedef struct
|
||||
{
|
||||
POINT position;
|
||||
int type;
|
||||
} ENTITY;
|
||||
|
||||
enum
|
||||
{
|
||||
CURVETYPE_STEP=0,
|
||||
CURVETYPE_LINEAR,
|
||||
CURVETYPE_SLOW,
|
||||
CURVETYPE_FAST,
|
||||
CURVETYPE_SMOOTH,
|
||||
NUM_CURVETYPES,
|
||||
|
||||
};
|
||||
|
||||
typedef struct // as in file
|
||||
{
|
||||
int time; // in ms
|
||||
int curvetype;
|
||||
int values[4]; // 1-4 depending on envelope (22.10 fixed point)
|
||||
} ENVPOINT;
|
||||
|
||||
class ENVELOPE
|
||||
{
|
||||
public:
|
||||
|
@ -86,10 +69,10 @@ public:
|
|||
void resort()
|
||||
{
|
||||
qsort(points.getptr(), points.len(), sizeof(ENVPOINT), sort_comp);
|
||||
find_top_bottom();
|
||||
find_top_bottom(0xf);
|
||||
}
|
||||
|
||||
void find_top_bottom()
|
||||
void find_top_bottom(int channelmask)
|
||||
{
|
||||
top = -1000000000.0f;
|
||||
bottom = 1000000000.0f;
|
||||
|
@ -97,54 +80,20 @@ public:
|
|||
{
|
||||
for(int c = 0; c < channels; c++)
|
||||
{
|
||||
float v = fx2f(points[i].values[c]);
|
||||
if(v > top) top = v;
|
||||
if(v < bottom) bottom = v;
|
||||
if(channelmask&(1<<c))
|
||||
{
|
||||
float v = fx2f(points[i].values[c]);
|
||||
if(v > top) top = v;
|
||||
if(v < bottom) bottom = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float eval(float time, int channel)
|
||||
int eval(float time, float *result)
|
||||
{
|
||||
if(channel >= channels)
|
||||
return 0;
|
||||
if(points.len() == 0)
|
||||
return 0;
|
||||
if(points.len() == 1)
|
||||
return points[0].values[channel];
|
||||
|
||||
time = fmod(time, end_time())*1000.0f;
|
||||
for(int i = 0; i < points.len() - 1; i++)
|
||||
{
|
||||
if(time >= points[i].time && time <= points[i+1].time)
|
||||
{
|
||||
float delta = points[i+1].time-points[i].time;
|
||||
float a = (time-points[i].time)/delta;
|
||||
|
||||
float v0 = fx2f(points[i].values[channel]);
|
||||
float v1 = fx2f(points[i+1].values[channel]);
|
||||
|
||||
if(points[i].curvetype == CURVETYPE_SMOOTH)
|
||||
a = -2*a*a*a + 3*a*a; // second hermite basis
|
||||
else if(points[i].curvetype == CURVETYPE_SLOW)
|
||||
a = a*a*a;
|
||||
else if(points[i].curvetype == CURVETYPE_FAST)
|
||||
{
|
||||
a = 1-a;
|
||||
a = 1-a*a*a;
|
||||
}
|
||||
else if (points[i].curvetype == CURVETYPE_STEP)
|
||||
a = 0;
|
||||
else
|
||||
{
|
||||
// linear
|
||||
}
|
||||
|
||||
return v0 + (v1-v0) * a;
|
||||
}
|
||||
}
|
||||
|
||||
return points[points.len()-1].values[channel];
|
||||
render_eval_envelope(points.getptr(), points.len(), channels, time, result);
|
||||
return channels;
|
||||
}
|
||||
|
||||
void add_point(int time, int v0, int v1=0, int v2=0, int v3=0)
|
||||
|
@ -310,12 +259,6 @@ enum
|
|||
PROPTYPE_COLOR,
|
||||
PROPTYPE_IMAGE,
|
||||
PROPTYPE_ENVELOPE,
|
||||
|
||||
PROPS_NONE=0,
|
||||
PROPS_GROUP,
|
||||
PROPS_LAYER,
|
||||
PROPS_QUAD,
|
||||
PROPS_QUAD_POINT,
|
||||
};
|
||||
|
||||
class EDITOR
|
||||
|
@ -347,8 +290,6 @@ public:
|
|||
animate_start = 0;
|
||||
animate_time = 0;
|
||||
|
||||
props = PROPS_NONE;
|
||||
|
||||
show_envelope_editor = 0;
|
||||
}
|
||||
|
||||
|
@ -362,6 +303,7 @@ public:
|
|||
void reset(bool create_default=true);
|
||||
int save(const char *filename);
|
||||
int load(const char *filename);
|
||||
void render();
|
||||
|
||||
QUAD *get_selected_quad();
|
||||
LAYER *get_selected_layer_type(int index, int type);
|
||||
|
@ -395,10 +337,14 @@ public:
|
|||
int64 animate_start;
|
||||
float animate_time;
|
||||
|
||||
int props;
|
||||
|
||||
int show_envelope_editor;
|
||||
|
||||
int selected_layer;
|
||||
int selected_group;
|
||||
int selected_quad;
|
||||
int selected_points;
|
||||
int selected_envelope;
|
||||
|
||||
MAP map;
|
||||
};
|
||||
|
||||
|
@ -468,7 +414,6 @@ public:
|
|||
array<QUAD> quads;
|
||||
};
|
||||
|
||||
|
||||
class LAYER_GAME : public LAYER_TILES
|
||||
{
|
||||
public:
|
||||
|
@ -481,3 +426,14 @@ public:
|
|||
int do_editor_button(const void *id, const char *text, int checked, const RECT *r, ui_draw_button_func draw_func, int flags, const char *tooltip);
|
||||
void draw_editor_button(const void *id, const char *text, int checked, const RECT *r, const void *extra);
|
||||
void draw_editor_button_menuitem(const void *id, const char *text, int checked, const RECT *r, const void *extra);
|
||||
|
||||
void ui_invoke_popup_menu(void *id, int flags, float x, float y, float w, float h, int (*func)(RECT rect), void *extra=0);
|
||||
void ui_do_popup_menu();
|
||||
|
||||
int popup_group(RECT view);
|
||||
int popup_layer(RECT view);
|
||||
int popup_quad(RECT view);
|
||||
int popup_point(RECT view);
|
||||
|
||||
void popup_select_image_invoke(int current, float x, float y);
|
||||
int popup_select_image_result();
|
||||
|
|
471
src/game/editor/ed_io.cpp
Normal file
471
src/game/editor/ed_io.cpp
Normal file
|
@ -0,0 +1,471 @@
|
|||
#include "ed_editor.hpp"
|
||||
|
||||
template<typename T>
|
||||
static int make_version(int i, const T &v)
|
||||
{ return (i<<16)+sizeof(T); }
|
||||
|
||||
// backwards compatiblity
|
||||
void editor_load_old(DATAFILE *df)
|
||||
{
|
||||
class mapres_image
|
||||
{
|
||||
public:
|
||||
int width;
|
||||
int height;
|
||||
int image_data;
|
||||
};
|
||||
|
||||
|
||||
struct mapres_tilemap
|
||||
{
|
||||
int image;
|
||||
int width;
|
||||
int height;
|
||||
int x, y;
|
||||
int scale;
|
||||
int data;
|
||||
int main;
|
||||
};
|
||||
|
||||
struct mapres_entity
|
||||
{
|
||||
int x, y;
|
||||
int data[1];
|
||||
};
|
||||
|
||||
struct mapres_spawnpoint
|
||||
{
|
||||
int x, y;
|
||||
};
|
||||
|
||||
struct mapres_item
|
||||
{
|
||||
int x, y;
|
||||
int type;
|
||||
};
|
||||
|
||||
struct mapres_flagstand
|
||||
{
|
||||
int x, y;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MAPRES_ENTS_START=1,
|
||||
MAPRES_SPAWNPOINT=1,
|
||||
MAPRES_ITEM=2,
|
||||
MAPRES_SPAWNPOINT_RED=3,
|
||||
MAPRES_SPAWNPOINT_BLUE=4,
|
||||
MAPRES_FLAGSTAND_RED=5,
|
||||
MAPRES_FLAGSTAND_BLUE=6,
|
||||
MAPRES_ENTS_END,
|
||||
|
||||
ITEM_NULL=0,
|
||||
ITEM_WEAPON_GUN=0x00010001,
|
||||
ITEM_WEAPON_SHOTGUN=0x00010002,
|
||||
ITEM_WEAPON_ROCKET=0x00010003,
|
||||
ITEM_WEAPON_SNIPER=0x00010004,
|
||||
ITEM_WEAPON_HAMMER=0x00010005,
|
||||
ITEM_HEALTH =0x00020001,
|
||||
ITEM_ARMOR=0x00030001,
|
||||
ITEM_NINJA=0x00040001,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MAPRES_REGISTERED=0x8000,
|
||||
MAPRES_IMAGE=0x8001,
|
||||
MAPRES_TILEMAP=0x8002,
|
||||
MAPRES_COLLISIONMAP=0x8003,
|
||||
MAPRES_TEMP_THEME=0x8fff,
|
||||
};
|
||||
|
||||
// load tilemaps
|
||||
int game_width = 0;
|
||||
int game_height = 0;
|
||||
{
|
||||
int start, num;
|
||||
datafile_get_type(df, MAPRES_TILEMAP, &start, &num);
|
||||
for(int t = 0; t < num; t++)
|
||||
{
|
||||
mapres_tilemap *tmap = (mapres_tilemap *)datafile_get_item(df, start+t,0,0);
|
||||
|
||||
LAYER_TILES *l = new LAYER_TILES(tmap->width, tmap->height);
|
||||
|
||||
if(tmap->main)
|
||||
{
|
||||
// move game layer to correct position
|
||||
for(int i = 0; i < editor.map.groups[0]->layers.len()-1; i++)
|
||||
{
|
||||
if(editor.map.groups[0]->layers[i] == editor.game_layer)
|
||||
editor.map.groups[0]->swap_layers(i, i+1);
|
||||
}
|
||||
|
||||
game_width = tmap->width;
|
||||
game_height = tmap->height;
|
||||
}
|
||||
|
||||
// add new layer
|
||||
editor.map.groups[0]->add_layer(l);
|
||||
|
||||
// process the data
|
||||
unsigned char *src_data = (unsigned char *)datafile_get_data(df, tmap->data);
|
||||
TILE *dst_data = l->tiles;
|
||||
|
||||
for(int y = 0; y < tmap->height; y++)
|
||||
for(int x = 0; x < tmap->width; x++, dst_data++, src_data+=2)
|
||||
{
|
||||
dst_data->index = src_data[0];
|
||||
dst_data->flags = src_data[1];
|
||||
}
|
||||
|
||||
l->image = tmap->image;
|
||||
}
|
||||
}
|
||||
|
||||
// load images
|
||||
{
|
||||
int start, count;
|
||||
datafile_get_type(df, MAPRES_IMAGE, &start, &count);
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
mapres_image *imgres = (mapres_image *)datafile_get_item(df, start+i, 0, 0);
|
||||
void *data = datafile_get_data(df, imgres->image_data);
|
||||
|
||||
IMAGE *img = new IMAGE;
|
||||
img->width = imgres->width;
|
||||
img->height = imgres->height;
|
||||
img->format = IMG_RGBA;
|
||||
|
||||
// copy image data
|
||||
img->data = mem_alloc(img->width*img->height*4, 1);
|
||||
mem_copy(img->data, data, img->width*img->height*4);
|
||||
img->tex_id = gfx_load_texture_raw(img->width, img->height, img->format, img->data, IMG_AUTO);
|
||||
editor.map.images.add(img);
|
||||
|
||||
// unload image
|
||||
datafile_unload_data(df, imgres->image_data);
|
||||
}
|
||||
}
|
||||
|
||||
// load entities
|
||||
{
|
||||
LAYER_GAME *g = editor.game_layer;
|
||||
g->resize(game_width, game_height);
|
||||
for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++)
|
||||
{
|
||||
// fetch entities of this class
|
||||
int start, num;
|
||||
datafile_get_type(df, t, &start, &num);
|
||||
|
||||
|
||||
for(int i = 0; i < num; i++)
|
||||
{
|
||||
mapres_entity *e = (mapres_entity *)datafile_get_item(df, start+i,0,0);
|
||||
int x = e->x/32;
|
||||
int y = e->y/32;
|
||||
int id = -1;
|
||||
|
||||
if(t == MAPRES_SPAWNPOINT) id = ENTITY_SPAWN;
|
||||
else if(t == MAPRES_SPAWNPOINT_RED) id = ENTITY_SPAWN_RED;
|
||||
else if(t == MAPRES_SPAWNPOINT_BLUE) id = ENTITY_SPAWN_BLUE;
|
||||
else if(t == MAPRES_FLAGSTAND_RED) id = ENTITY_FLAGSTAND_RED;
|
||||
else if(t == MAPRES_FLAGSTAND_BLUE) id = ENTITY_FLAGSTAND_BLUE;
|
||||
else if(t == MAPRES_ITEM)
|
||||
{
|
||||
if(e->data[0] == ITEM_WEAPON_SHOTGUN) id = ENTITY_WEAPON_SHOTGUN;
|
||||
else if(e->data[0] == ITEM_WEAPON_ROCKET) id = ENTITY_WEAPON_ROCKET;
|
||||
else if(e->data[0] == ITEM_NINJA) id = ENTITY_POWERUP_NINJA;
|
||||
else if(e->data[0] == ITEM_ARMOR) id = ENTITY_ARMOR_1;
|
||||
else if(e->data[0] == ITEM_HEALTH) id = ENTITY_HEALTH_1;
|
||||
}
|
||||
|
||||
if(id > 0 && x >= 0 && x < g->width && y >= 0 && y < g->height)
|
||||
g->tiles[y*g->width+x].index = id+ENTITY_OFFSET;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int EDITOR::save(const char *filename)
|
||||
{
|
||||
dbg_msg("editor", "saving to '%s'...", filename);
|
||||
DATAFILE_OUT *df = datafile_create(filename);
|
||||
if(!df)
|
||||
{
|
||||
dbg_msg("editor", "failed to open file '%s'...", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// save version
|
||||
{
|
||||
MAPITEM_VERSION item;
|
||||
item.version = 1;
|
||||
datafile_add_item(df, MAPITEMTYPE_VERSION, 0, sizeof(item), &item);
|
||||
}
|
||||
|
||||
// save images
|
||||
for(int i = 0; i < map.images.len(); i++)
|
||||
{
|
||||
IMAGE *img = map.images[i];
|
||||
MAPITEM_IMAGE item;
|
||||
item.version = 1;
|
||||
|
||||
item.width = img->width;
|
||||
item.height = img->height;
|
||||
item.external = 0;
|
||||
item.image_name = -1;
|
||||
item.image_data = datafile_add_data(df, item.width*item.height*4, img->data);
|
||||
datafile_add_item(df, MAPITEMTYPE_IMAGE, i, sizeof(item), &item);
|
||||
}
|
||||
|
||||
// save layers
|
||||
int layer_count = 0;
|
||||
for(int g = 0; g < map.groups.len(); g++)
|
||||
{
|
||||
LAYERGROUP *group = map.groups[g];
|
||||
MAPITEM_GROUP gitem;
|
||||
gitem.version = 1;
|
||||
|
||||
gitem.parallax_x = group->parallax_x;
|
||||
gitem.parallax_y = group->parallax_y;
|
||||
gitem.offset_x = group->offset_x;
|
||||
gitem.offset_y = group->offset_y;
|
||||
gitem.start_layer = layer_count;
|
||||
gitem.num_layers = 0;
|
||||
|
||||
for(int l = 0; l < group->layers.len(); l++)
|
||||
{
|
||||
if(group->layers[l]->type == LAYERTYPE_TILES)
|
||||
{
|
||||
dbg_msg("editor", "saving tiles layer");
|
||||
LAYER_TILES *layer = (LAYER_TILES *)group->layers[l];
|
||||
MAPITEM_LAYER_TILEMAP item;
|
||||
item.version = 2;
|
||||
|
||||
item.layer.flags = 0;
|
||||
item.layer.type = layer->type;
|
||||
|
||||
item.color.r = 255; // not in use right now
|
||||
item.color.g = 255;
|
||||
item.color.b = 255;
|
||||
item.color.a = 255;
|
||||
item.color_env = -1;
|
||||
item.color_env_offset = 0;
|
||||
|
||||
item.width = layer->width;
|
||||
item.height = layer->height;
|
||||
item.flags = layer->game;
|
||||
item.image = layer->image;
|
||||
item.data = datafile_add_data(df, layer->width*layer->height*sizeof(TILE), layer->tiles);
|
||||
datafile_add_item(df, MAPITEMTYPE_LAYER, layer_count, sizeof(item), &item);
|
||||
|
||||
gitem.num_layers++;
|
||||
layer_count++;
|
||||
}
|
||||
else if(group->layers[l]->type == LAYERTYPE_QUADS)
|
||||
{
|
||||
dbg_msg("editor", "saving quads layer");
|
||||
LAYER_QUADS *layer = (LAYER_QUADS *)group->layers[l];
|
||||
if(layer->quads.len())
|
||||
{
|
||||
MAPITEM_LAYER_QUADS item;
|
||||
item.version = 1;
|
||||
item.layer.flags = 0;
|
||||
item.layer.type = layer->type;
|
||||
item.image = layer->image;
|
||||
|
||||
// add the data
|
||||
item.num_quads = layer->quads.len();
|
||||
item.data = datafile_add_data_swapped(df, layer->quads.len()*sizeof(QUAD), layer->quads.getptr());
|
||||
datafile_add_item(df, MAPITEMTYPE_LAYER, layer_count, sizeof(item), &item);
|
||||
|
||||
// clean up
|
||||
//mem_free(quads);
|
||||
|
||||
gitem.num_layers++;
|
||||
layer_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
datafile_add_item(df, MAPITEMTYPE_GROUP, g, sizeof(gitem), &gitem);
|
||||
}
|
||||
|
||||
// save envelopes
|
||||
int point_count = 0;
|
||||
for(int e = 0; e < map.envelopes.len(); e++)
|
||||
{
|
||||
MAPITEM_ENVELOPE item;
|
||||
item.version = 1;
|
||||
item.channels = map.envelopes[e]->channels;
|
||||
item.start_point = point_count;
|
||||
item.num_points = map.envelopes[e]->points.len();
|
||||
item.name = -1;
|
||||
|
||||
datafile_add_item(df, MAPITEMTYPE_ENVELOPE, e, sizeof(item), &item);
|
||||
point_count += item.num_points;
|
||||
}
|
||||
|
||||
// save points
|
||||
int totalsize = sizeof(ENVPOINT) * point_count;
|
||||
ENVPOINT *points = (ENVPOINT *)mem_alloc(totalsize, 1);
|
||||
point_count = 0;
|
||||
|
||||
for(int e = 0; e < map.envelopes.len(); e++)
|
||||
{
|
||||
int count = map.envelopes[e]->points.len();
|
||||
mem_copy(&points[point_count], map.envelopes[e]->points.getptr(), sizeof(ENVPOINT)*count);
|
||||
point_count += count;
|
||||
}
|
||||
|
||||
datafile_add_item(df, MAPITEMTYPE_ENVPOINTS, 0, totalsize, points);
|
||||
|
||||
// finish the data file
|
||||
datafile_finish(df);
|
||||
dbg_msg("editor", "done");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EDITOR::load(const char *filename)
|
||||
{
|
||||
DATAFILE *df = datafile_load(filename);
|
||||
if(!df)
|
||||
return 0;
|
||||
|
||||
// check version
|
||||
MAPITEM_VERSION *item = (MAPITEM_VERSION *)datafile_find_item(df, MAPITEMTYPE_VERSION, 0);
|
||||
if(!item)
|
||||
{
|
||||
// import old map
|
||||
editor.reset();
|
||||
editor_load_old(df);
|
||||
}
|
||||
else if(item->version == 1)
|
||||
{
|
||||
editor.reset(false);
|
||||
|
||||
// load images
|
||||
{
|
||||
int start, num;
|
||||
datafile_get_type(df, MAPITEMTYPE_IMAGE, &start, &num);
|
||||
for(int i = 0; i < num; i++)
|
||||
{
|
||||
MAPITEM_IMAGE *item = (MAPITEM_IMAGE *)datafile_get_item(df, start+i, 0, 0);
|
||||
void *data = datafile_get_data(df, item->image_data);
|
||||
|
||||
IMAGE *img = new IMAGE;
|
||||
img->width = item->width;
|
||||
img->height = item->height;
|
||||
img->format = IMG_RGBA;
|
||||
|
||||
// copy image data
|
||||
img->data = mem_alloc(img->width*img->height*4, 1);
|
||||
mem_copy(img->data, data, img->width*img->height*4);
|
||||
img->tex_id = gfx_load_texture_raw(img->width, img->height, img->format, img->data, IMG_AUTO);
|
||||
editor.map.images.add(img);
|
||||
|
||||
// unload image
|
||||
datafile_unload_data(df, item->image_data);
|
||||
}
|
||||
}
|
||||
|
||||
// load groups
|
||||
{
|
||||
int layers_start, layers_num;
|
||||
datafile_get_type(df, MAPITEMTYPE_LAYER, &layers_start, &layers_num);
|
||||
|
||||
int start, num;
|
||||
datafile_get_type(df, MAPITEMTYPE_GROUP, &start, &num);
|
||||
for(int g = 0; g < num; g++)
|
||||
{
|
||||
MAPITEM_GROUP *gitem = (MAPITEM_GROUP *)datafile_get_item(df, start+g, 0, 0);
|
||||
LAYERGROUP *group = map.new_group();
|
||||
group->parallax_x = gitem->parallax_x;
|
||||
group->parallax_y = gitem->parallax_y;
|
||||
group->offset_x = gitem->offset_x;
|
||||
group->offset_y = gitem->offset_y;
|
||||
|
||||
for(int l = 0; l < gitem->num_layers; l++)
|
||||
{
|
||||
MAPITEM_LAYER *layer_item = (MAPITEM_LAYER *)datafile_get_item(df, layers_start+gitem->start_layer+l, 0, 0);
|
||||
if(!layer_item)
|
||||
continue;
|
||||
|
||||
if(layer_item->type == LAYERTYPE_TILES)
|
||||
{
|
||||
MAPITEM_LAYER_TILEMAP *tilemap_item = (MAPITEM_LAYER_TILEMAP *)layer_item;
|
||||
LAYER_TILES *tiles = 0;
|
||||
|
||||
if(tilemap_item->flags&1)
|
||||
{
|
||||
tiles = new LAYER_GAME(tilemap_item->width, tilemap_item->height);
|
||||
editor.make_game_layer(tiles);
|
||||
make_game_group(group);
|
||||
}
|
||||
else
|
||||
tiles = new LAYER_TILES(tilemap_item->width, tilemap_item->height);
|
||||
|
||||
group->add_layer(tiles);
|
||||
void *data = datafile_get_data(df, tilemap_item->data);
|
||||
tiles->image = tilemap_item->image;
|
||||
tiles->game = tilemap_item->flags&1;
|
||||
|
||||
mem_copy(tiles->tiles, data, tiles->width*tiles->height*sizeof(TILE));
|
||||
|
||||
if(tiles->game && tilemap_item->version == make_version(1, *tilemap_item))
|
||||
{
|
||||
for(int i = 0; i < tiles->width*tiles->height; i++)
|
||||
{
|
||||
if(tiles->tiles[i].index)
|
||||
tiles->tiles[i].index += ENTITY_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
datafile_unload_data(df, tilemap_item->data);
|
||||
}
|
||||
else if(layer_item->type == LAYERTYPE_QUADS)
|
||||
{
|
||||
MAPITEM_LAYER_QUADS *quads_item = (MAPITEM_LAYER_QUADS *)layer_item;
|
||||
LAYER_QUADS *layer = new LAYER_QUADS;
|
||||
layer->image = quads_item->image;
|
||||
if(layer->image < -1 || layer->image >= map.images.len())
|
||||
layer->image = -1;
|
||||
void *data = datafile_get_data_swapped(df, quads_item->data);
|
||||
group->add_layer(layer);
|
||||
layer->quads.setsize(quads_item->num_quads);
|
||||
mem_copy(layer->quads.getptr(), data, sizeof(QUAD)*quads_item->num_quads);
|
||||
datafile_unload_data(df, quads_item->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// load envelopes
|
||||
{
|
||||
ENVPOINT *points = 0;
|
||||
|
||||
{
|
||||
int start, num;
|
||||
datafile_get_type(df, MAPITEMTYPE_ENVPOINTS, &start, &num);
|
||||
if(num)
|
||||
points = (ENVPOINT *)datafile_get_item(df, start, 0, 0);
|
||||
}
|
||||
|
||||
int start, num;
|
||||
datafile_get_type(df, MAPITEMTYPE_ENVELOPE, &start, &num);
|
||||
for(int e = 0; e < num; e++)
|
||||
{
|
||||
MAPITEM_ENVELOPE *item = (MAPITEM_ENVELOPE *)datafile_get_item(df, start+e, 0, 0);
|
||||
ENVELOPE *env = new ENVELOPE(item->channels);
|
||||
env->points.setsize(item->num_points);
|
||||
mem_copy(env->points.getptr(), &points[item->start_point], sizeof(ENVPOINT)*item->num_points);
|
||||
map.envelopes.add(env);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
datafile_unload(df);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -14,13 +14,20 @@ LAYER_QUADS::~LAYER_QUADS()
|
|||
{
|
||||
}
|
||||
|
||||
static void envelope_eval(float time_offset, int env, float *channels)
|
||||
{
|
||||
ENVELOPE *e = editor.map.envelopes[env];
|
||||
float t = editor.animate_time+time_offset;
|
||||
e->eval(t, channels);
|
||||
}
|
||||
|
||||
void LAYER_QUADS::render()
|
||||
{
|
||||
gfx_texture_set(-1);
|
||||
if(image >= 0 && image < editor.map.images.len())
|
||||
gfx_texture_set(editor.map.images[image]->tex_id);
|
||||
|
||||
render_quads(quads.getptr(), quads.len());
|
||||
render_quads(quads.getptr(), quads.len(), envelope_eval);
|
||||
}
|
||||
|
||||
QUAD *LAYER_QUADS::new_quad()
|
||||
|
@ -160,123 +167,29 @@ extern int selected_points;
|
|||
int LAYER_QUADS::render_properties(RECT *toolbox)
|
||||
{
|
||||
// layer props
|
||||
if(editor.props == PROPS_LAYER)
|
||||
enum
|
||||
{
|
||||
enum
|
||||
{
|
||||
PROP_IMAGE=0,
|
||||
NUM_PROPS,
|
||||
};
|
||||
|
||||
PROPERTY props[] = {
|
||||
{"Image", image, PROPTYPE_IMAGE, -1, 0},
|
||||
{0},
|
||||
};
|
||||
|
||||
static int ids[NUM_PROPS] = {0};
|
||||
int new_val = 0;
|
||||
int prop = editor.do_properties(toolbox, props, ids, &new_val);
|
||||
|
||||
if(prop == PROP_IMAGE)
|
||||
{
|
||||
if(new_val >= 0)
|
||||
image = new_val%editor.map.images.len();
|
||||
else
|
||||
image = -1;
|
||||
}
|
||||
PROP_IMAGE=0,
|
||||
NUM_PROPS,
|
||||
};
|
||||
|
||||
PROPERTY props[] = {
|
||||
{"Image", image, PROPTYPE_IMAGE, -1, 0},
|
||||
{0},
|
||||
};
|
||||
|
||||
static int ids[NUM_PROPS] = {0};
|
||||
int new_val = 0;
|
||||
int prop = editor.do_properties(toolbox, props, ids, &new_val);
|
||||
|
||||
if(prop == PROP_IMAGE)
|
||||
{
|
||||
if(new_val >= 0)
|
||||
image = new_val%editor.map.images.len();
|
||||
else
|
||||
image = -1;
|
||||
}
|
||||
|
||||
// quad props
|
||||
QUAD *quad = editor.get_selected_quad();
|
||||
if(editor.props == PROPS_QUAD)
|
||||
{
|
||||
if(quad)
|
||||
{
|
||||
RECT slot;
|
||||
ui_hsplit_t(toolbox, 15.0f, &slot, toolbox);
|
||||
ui_do_label(&slot, "Quad Props", 12.0f, -1, -1);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_POS_ENV=0,
|
||||
PROP_POS_ENV_OFFSET,
|
||||
PROP_COLOR_ENV,
|
||||
PROP_COLOR_ENV_OFFSET,
|
||||
NUM_PROPS,
|
||||
};
|
||||
|
||||
PROPERTY props[] = {
|
||||
{"Pos. Env", quad->pos_env, PROPTYPE_INT_STEP, -1, editor.map.envelopes.len()},
|
||||
{"Pos. TO", quad->pos_env_offset, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||
{"Color Env", quad->color_env, PROPTYPE_INT_STEP, -1, editor.map.envelopes.len()},
|
||||
{"Color TO", quad->color_env_offset, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||
|
||||
{0},
|
||||
};
|
||||
|
||||
static int ids[NUM_PROPS] = {0};
|
||||
int new_val = 0;
|
||||
int prop = editor.do_properties(toolbox, props, ids, &new_val);
|
||||
|
||||
if(prop == PROP_POS_ENV) quad->pos_env = new_val;
|
||||
if(prop == PROP_POS_ENV_OFFSET) quad->pos_env_offset = new_val;
|
||||
if(prop == PROP_COLOR_ENV) quad->color_env = new_val;
|
||||
if(prop == PROP_COLOR_ENV_OFFSET) quad->color_env_offset = new_val;
|
||||
}
|
||||
}
|
||||
|
||||
// point props
|
||||
if(editor.props == PROPS_QUAD_POINT && quad && selected_points)
|
||||
{
|
||||
RECT slot;
|
||||
ui_hsplit_t(toolbox, 15.0f, &slot, toolbox);
|
||||
ui_do_label(&slot, "Point Props", 14.0f, -1, -1);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_COLOR=0,
|
||||
NUM_PROPS,
|
||||
};
|
||||
|
||||
int color = 0;
|
||||
|
||||
for(int v = 0; v < 4; v++)
|
||||
{
|
||||
if(selected_points&(1<<v))
|
||||
{
|
||||
color = 0;
|
||||
color |= quad->colors[v].r<<24;
|
||||
color |= quad->colors[v].g<<16;
|
||||
color |= quad->colors[v].b<<8;
|
||||
color |= quad->colors[v].a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PROPERTY props[] = {
|
||||
{"Color", color, PROPTYPE_COLOR, -1, editor.map.envelopes.len()},
|
||||
{0},
|
||||
};
|
||||
|
||||
static int ids[NUM_PROPS] = {0};
|
||||
int new_val = 0;
|
||||
int prop = editor.do_properties(toolbox, props, ids, &new_val);
|
||||
if(prop == PROP_COLOR)
|
||||
{
|
||||
for(int v = 0; v < 4; v++)
|
||||
{
|
||||
if(selected_points&(1<<v))
|
||||
{
|
||||
color = 0;
|
||||
quad->colors[v].r = (new_val>>24)&0xff;
|
||||
quad->colors[v].g = (new_val>>16)&0xff;
|
||||
quad->colors[v].b = (new_val>>8)&0xff;
|
||||
quad->colors[v].a = new_val&0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ int LAYER_TILES::render_properties(RECT *toolbox)
|
|||
};
|
||||
|
||||
PROPERTY props[] = {
|
||||
{"Image", image, PROPTYPE_INT_STEP, 0, 0},
|
||||
{"Image", image, PROPTYPE_IMAGE, 0, 0},
|
||||
{"Width", width, PROPTYPE_INT_STEP, 1, 1000000000},
|
||||
{"Height", height, PROPTYPE_INT_STEP, 1, 1000000000},
|
||||
{0},
|
||||
|
|
385
src/game/editor/ed_popups.cpp
Normal file
385
src/game/editor/ed_popups.cpp
Normal file
|
@ -0,0 +1,385 @@
|
|||
#include <stdio.h>
|
||||
#include "ed_editor.hpp"
|
||||
|
||||
|
||||
// popup menu handling
|
||||
static struct
|
||||
{
|
||||
RECT rect;
|
||||
void *id;
|
||||
int (*func)(RECT rect);
|
||||
int is_menu;
|
||||
void *extra;
|
||||
} ui_popups[8];
|
||||
|
||||
static int ui_num_popups = 0;
|
||||
|
||||
void ui_invoke_popup_menu(void *id, int flags, float x, float y, float w, float h, int (*func)(RECT rect), void *extra)
|
||||
{
|
||||
dbg_msg("", "invoked");
|
||||
ui_popups[ui_num_popups].id = id;
|
||||
ui_popups[ui_num_popups].is_menu = flags;
|
||||
ui_popups[ui_num_popups].rect.x = x;
|
||||
ui_popups[ui_num_popups].rect.y = y;
|
||||
ui_popups[ui_num_popups].rect.w = w;
|
||||
ui_popups[ui_num_popups].rect.h = h;
|
||||
ui_popups[ui_num_popups].func = func;
|
||||
ui_popups[ui_num_popups].extra = extra;
|
||||
ui_num_popups++;
|
||||
}
|
||||
|
||||
void ui_do_popup_menu()
|
||||
{
|
||||
for(int i = 0; i < ui_num_popups; i++)
|
||||
{
|
||||
bool inside = ui_mouse_inside(&ui_popups[i].rect);
|
||||
ui_set_hot_item(&ui_popups[i].id);
|
||||
|
||||
if(ui_active_item() == &ui_popups[i].id)
|
||||
{
|
||||
if(!ui_mouse_button(0))
|
||||
{
|
||||
if(!inside)
|
||||
ui_num_popups--;
|
||||
ui_set_active_item(0);
|
||||
}
|
||||
}
|
||||
else if(ui_hot_item() == &ui_popups[i].id)
|
||||
{
|
||||
if(ui_mouse_button(0))
|
||||
ui_set_active_item(&ui_popups[i].id);
|
||||
}
|
||||
|
||||
int corners = CORNER_ALL;
|
||||
if(ui_popups[i].is_menu)
|
||||
corners = CORNER_R|CORNER_B;
|
||||
|
||||
RECT r = ui_popups[i].rect;
|
||||
ui_draw_rect(&r, vec4(0.5f,0.5f,0.5f,0.75f), corners, 3.0f);
|
||||
ui_margin(&r, 1.0f, &r);
|
||||
ui_draw_rect(&r, vec4(0,0,0,0.75f), corners, 3.0f);
|
||||
ui_margin(&r, 4.0f, &r);
|
||||
|
||||
if(ui_popups[i].func(r))
|
||||
ui_num_popups--;
|
||||
|
||||
if(inp_key_down(KEY_ESC))
|
||||
ui_num_popups--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int popup_group(RECT view)
|
||||
{
|
||||
// remove group button
|
||||
RECT button;
|
||||
ui_hsplit_b(&view, 12.0f, &view, &button);
|
||||
static int delete_button = 0;
|
||||
if(do_editor_button(&delete_button, "Delete Group", 0, &button, draw_editor_button, 0, "Delete group"))
|
||||
{
|
||||
editor.map.delete_group(editor.selected_group);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// new tile layer
|
||||
ui_hsplit_b(&view, 10.0f, &view, &button);
|
||||
ui_hsplit_b(&view, 12.0f, &view, &button);
|
||||
static int new_quad_layer_button = 0;
|
||||
if(do_editor_button(&new_quad_layer_button, "Add Quads Layer", 0, &button, draw_editor_button, 0, "Creates a new quad layer"))
|
||||
{
|
||||
LAYER *l = new LAYER_QUADS;
|
||||
editor.map.groups[editor.selected_group]->add_layer(l);
|
||||
editor.selected_layer = editor.map.groups[editor.selected_group]->layers.len()-1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// new quad layer
|
||||
ui_hsplit_b(&view, 5.0f, &view, &button);
|
||||
ui_hsplit_b(&view, 12.0f, &view, &button);
|
||||
static int new_tile_layer_button = 0;
|
||||
if(do_editor_button(&new_tile_layer_button, "Add Tile Layer", 0, &button, draw_editor_button, 0, "Creates a new tile layer"))
|
||||
{
|
||||
LAYER *l = new LAYER_TILES(50, 50);
|
||||
editor.map.groups[editor.selected_group]->add_layer(l);
|
||||
editor.selected_layer = editor.map.groups[editor.selected_group]->layers.len()-1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_ORDER=0,
|
||||
PROP_POS_X,
|
||||
PROP_POS_Y,
|
||||
PROP_PARA_X,
|
||||
PROP_PARA_Y,
|
||||
NUM_PROPS,
|
||||
};
|
||||
|
||||
PROPERTY props[] = {
|
||||
{"Order", editor.selected_group, PROPTYPE_INT_STEP, 0, editor.map.groups.len()-1},
|
||||
{"Pos X", -editor.map.groups[editor.selected_group]->offset_x, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||
{"Pos Y", -editor.map.groups[editor.selected_group]->offset_y, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||
{"Para X", editor.map.groups[editor.selected_group]->parallax_x, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||
{"Para Y", editor.map.groups[editor.selected_group]->parallax_y, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||
{0},
|
||||
};
|
||||
|
||||
static int ids[NUM_PROPS] = {0};
|
||||
int new_val = 0;
|
||||
|
||||
// cut the properties that isn't needed
|
||||
if(editor.get_selected_group()->game_group)
|
||||
props[PROP_POS_X].name = 0;
|
||||
|
||||
int prop = editor.do_properties(&view, props, ids, &new_val);
|
||||
if(prop == PROP_ORDER)
|
||||
editor.selected_group = editor.map.swap_groups(editor.selected_group, new_val);
|
||||
|
||||
// these can not be changed on the game group
|
||||
if(!editor.get_selected_group()->game_group)
|
||||
{
|
||||
if(prop == PROP_PARA_X)
|
||||
editor.map.groups[editor.selected_group]->parallax_x = new_val;
|
||||
else if(prop == PROP_PARA_Y)
|
||||
editor.map.groups[editor.selected_group]->parallax_y = new_val;
|
||||
else if(prop == PROP_POS_X)
|
||||
editor.map.groups[editor.selected_group]->offset_x = -new_val;
|
||||
else if(prop == PROP_POS_Y)
|
||||
editor.map.groups[editor.selected_group]->offset_y = -new_val;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int popup_layer(RECT view)
|
||||
{
|
||||
// remove layer button
|
||||
RECT button;
|
||||
ui_hsplit_b(&view, 12.0f, &view, &button);
|
||||
static int delete_button = 0;
|
||||
if(do_editor_button(&delete_button, "Delete Layer", 0, &button, draw_editor_button, 0, "Deletes the layer"))
|
||||
{
|
||||
editor.map.groups[editor.selected_group]->delete_layer(editor.selected_layer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ui_hsplit_b(&view, 10.0f, &view, 0);
|
||||
|
||||
LAYERGROUP *current_group = editor.map.groups[editor.selected_group];
|
||||
LAYER *current_layer = editor.get_selected_layer(0);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_GROUP=0,
|
||||
PROP_ORDER,
|
||||
NUM_PROPS,
|
||||
};
|
||||
|
||||
PROPERTY props[] = {
|
||||
{"Group", editor.selected_group, PROPTYPE_INT_STEP, 0, editor.map.groups.len()-1},
|
||||
{"Order", editor.selected_layer, PROPTYPE_INT_STEP, 0, current_group->layers.len()},
|
||||
{0},
|
||||
};
|
||||
|
||||
static int ids[NUM_PROPS] = {0};
|
||||
int new_val = 0;
|
||||
int prop = editor.do_properties(&view, props, ids, &new_val);
|
||||
|
||||
if(prop == PROP_ORDER)
|
||||
editor.selected_layer = current_group->swap_layers(editor.selected_layer, new_val);
|
||||
else if(prop == PROP_GROUP && current_layer->type != LAYERTYPE_GAME)
|
||||
{
|
||||
if(new_val >= 0 && new_val < editor.map.groups.len())
|
||||
{
|
||||
current_group->layers.remove(current_layer);
|
||||
editor.map.groups[new_val]->layers.add(current_layer);
|
||||
editor.selected_group = new_val;
|
||||
editor.selected_layer = editor.map.groups[new_val]->layers.len()-1;
|
||||
}
|
||||
}
|
||||
|
||||
return current_layer->render_properties(&view);
|
||||
}
|
||||
|
||||
int popup_quad(RECT view)
|
||||
{
|
||||
QUAD *quad = editor.get_selected_quad();
|
||||
|
||||
RECT button;
|
||||
ui_hsplit_b(&view, 12.0f, &view, &button);
|
||||
static int sq_button = 0;
|
||||
if(do_editor_button(&sq_button, "Square", 0, &button, draw_editor_button, 0, "Squares the current quad"))
|
||||
{
|
||||
int top = quad->points[0].y;
|
||||
int left = quad->points[0].x;
|
||||
int bottom = quad->points[0].y;
|
||||
int right = quad->points[0].x;
|
||||
|
||||
for(int k = 1; k < 4; k++)
|
||||
{
|
||||
if(quad->points[k].y < top) top = quad->points[k].y;
|
||||
if(quad->points[k].x < left) left = quad->points[k].x;
|
||||
if(quad->points[k].y > bottom) bottom = quad->points[k].y;
|
||||
if(quad->points[k].x > right) right = quad->points[k].x;
|
||||
}
|
||||
|
||||
quad->points[0].x = left; quad->points[0].y = top;
|
||||
quad->points[1].x = right; quad->points[1].y = top;
|
||||
quad->points[2].x = left; quad->points[2].y = bottom;
|
||||
quad->points[3].x = right; quad->points[3].y = bottom;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//ui_vsplit_b(&toolbar, 2.0f, &button, &toolbar);
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_POS_ENV=0,
|
||||
PROP_POS_ENV_OFFSET,
|
||||
PROP_COLOR_ENV,
|
||||
PROP_COLOR_ENV_OFFSET,
|
||||
NUM_PROPS,
|
||||
};
|
||||
|
||||
PROPERTY props[] = {
|
||||
{"Pos. Env", quad->pos_env, PROPTYPE_INT_STEP, -1, editor.map.envelopes.len()},
|
||||
{"Pos. TO", quad->pos_env_offset, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||
{"Color Env", quad->color_env, PROPTYPE_INT_STEP, -1, editor.map.envelopes.len()},
|
||||
{"Color TO", quad->color_env_offset, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||
|
||||
{0},
|
||||
};
|
||||
|
||||
static int ids[NUM_PROPS] = {0};
|
||||
int new_val = 0;
|
||||
int prop = editor.do_properties(&view, props, ids, &new_val);
|
||||
|
||||
if(prop == PROP_POS_ENV) quad->pos_env = new_val;
|
||||
if(prop == PROP_POS_ENV_OFFSET) quad->pos_env_offset = new_val;
|
||||
if(prop == PROP_COLOR_ENV) quad->color_env = new_val;
|
||||
if(prop == PROP_COLOR_ENV_OFFSET) quad->color_env_offset = new_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int popup_point(RECT view)
|
||||
{
|
||||
QUAD *quad = editor.get_selected_quad();
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_COLOR=0,
|
||||
NUM_PROPS,
|
||||
};
|
||||
|
||||
int color = 0;
|
||||
|
||||
for(int v = 0; v < 4; v++)
|
||||
{
|
||||
if(editor.selected_points&(1<<v))
|
||||
{
|
||||
color = 0;
|
||||
color |= quad->colors[v].r<<24;
|
||||
color |= quad->colors[v].g<<16;
|
||||
color |= quad->colors[v].b<<8;
|
||||
color |= quad->colors[v].a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PROPERTY props[] = {
|
||||
{"Color", color, PROPTYPE_COLOR, -1, editor.map.envelopes.len()},
|
||||
{0},
|
||||
};
|
||||
|
||||
static int ids[NUM_PROPS] = {0};
|
||||
int new_val = 0;
|
||||
int prop = editor.do_properties(&view, props, ids, &new_val);
|
||||
if(prop == PROP_COLOR)
|
||||
{
|
||||
for(int v = 0; v < 4; v++)
|
||||
{
|
||||
if(editor.selected_points&(1<<v))
|
||||
{
|
||||
color = 0;
|
||||
quad->colors[v].r = (new_val>>24)&0xff;
|
||||
quad->colors[v].g = (new_val>>16)&0xff;
|
||||
quad->colors[v].b = (new_val>>8)&0xff;
|
||||
quad->colors[v].a = new_val&0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int select_image_selected = -100;
|
||||
static int select_image_current = -100;
|
||||
|
||||
int popup_select_image(RECT view)
|
||||
{
|
||||
RECT buttonbar, imageview;
|
||||
ui_vsplit_l(&view, 80.0f, &buttonbar, &view);
|
||||
ui_margin(&view, 10.0f, &imageview);
|
||||
|
||||
int show_image = select_image_current;
|
||||
|
||||
for(int i = -1; i < editor.map.images.len(); i++)
|
||||
{
|
||||
RECT button;
|
||||
ui_hsplit_t(&buttonbar, 12.0f, &button, &buttonbar);
|
||||
ui_hsplit_t(&buttonbar, 2.0f, 0, &buttonbar);
|
||||
|
||||
if(ui_mouse_inside(&button))
|
||||
show_image = i;
|
||||
|
||||
if(i == -1)
|
||||
{
|
||||
if(do_editor_button(&editor.map.images[i], "None", i==select_image_current, &button, draw_editor_button_menuitem, 0, 0))
|
||||
select_image_selected = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[64];
|
||||
sprintf(buf, "%d", i);
|
||||
if(do_editor_button(&editor.map.images[i], buf, i==select_image_current, &button, draw_editor_button_menuitem, 0, 0))
|
||||
select_image_selected = i;
|
||||
}
|
||||
}
|
||||
|
||||
if(show_image >= 0 && show_image < editor.map.images.len())
|
||||
gfx_texture_set(editor.map.images[show_image]->tex_id);
|
||||
else
|
||||
gfx_texture_set(-1);
|
||||
gfx_quads_begin();
|
||||
gfx_quads_drawTL(imageview.x, imageview.y, imageview.w, imageview.h);
|
||||
gfx_quads_end();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void popup_select_image_invoke(int current, float x, float y)
|
||||
{
|
||||
static int select_image_popup_id = 0;
|
||||
select_image_selected = -100;
|
||||
select_image_current = current;
|
||||
ui_invoke_popup_menu(&select_image_popup_id, 0, x, y, 400, 300, popup_select_image);
|
||||
}
|
||||
|
||||
int popup_select_image_result()
|
||||
{
|
||||
if(select_image_selected == -100)
|
||||
return -100;
|
||||
|
||||
select_image_current = select_image_selected;
|
||||
select_image_selected = -100;
|
||||
return select_image_current;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -129,48 +129,4 @@ public:
|
|||
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); }
|
||||
|
||||
struct mapres_entity
|
||||
{
|
||||
int x, y;
|
||||
int data[1];
|
||||
};
|
||||
|
||||
struct mapres_spawnpoint
|
||||
{
|
||||
int x, y;
|
||||
};
|
||||
|
||||
struct mapres_item
|
||||
{
|
||||
int x, y;
|
||||
int type;
|
||||
};
|
||||
|
||||
struct mapres_flagstand
|
||||
{
|
||||
int x, y;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MAPRES_ENTS_START=1,
|
||||
MAPRES_SPAWNPOINT=1,
|
||||
MAPRES_ITEM=2,
|
||||
MAPRES_SPAWNPOINT_RED=3,
|
||||
MAPRES_SPAWNPOINT_BLUE=4,
|
||||
MAPRES_FLAGSTAND_RED=5,
|
||||
MAPRES_FLAGSTAND_BLUE=6,
|
||||
MAPRES_ENTS_END,
|
||||
|
||||
ITEM_NULL=0,
|
||||
ITEM_WEAPON_GUN=0x00010001,
|
||||
ITEM_WEAPON_SHOTGUN=0x00010002,
|
||||
ITEM_WEAPON_ROCKET=0x00010003,
|
||||
ITEM_WEAPON_SNIPER=0x00010004,
|
||||
ITEM_WEAPON_HAMMER=0x00010005,
|
||||
ITEM_HEALTH =0x00020001,
|
||||
ITEM_ARMOR=0x00030001,
|
||||
ITEM_NINJA=0x00040001,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,15 @@ enum
|
|||
MAPITEMTYPE_ENVELOPE,
|
||||
MAPITEMTYPE_GROUP,
|
||||
MAPITEMTYPE_LAYER,
|
||||
MAPITEMTYPE_ENVPOINTS,
|
||||
|
||||
|
||||
CURVETYPE_STEP=0,
|
||||
CURVETYPE_LINEAR,
|
||||
CURVETYPE_SLOW,
|
||||
CURVETYPE_FAST,
|
||||
CURVETYPE_SMOOTH,
|
||||
NUM_CURVETYPES,
|
||||
|
||||
// game layer tiles
|
||||
ENTITY_NULL=0,
|
||||
|
@ -133,6 +142,22 @@ typedef struct
|
|||
int version;
|
||||
} MAPITEM_VERSION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int time; // in ms
|
||||
int curvetype;
|
||||
int values[4]; // 1-4 depending on envelope (22.10 fixed point)
|
||||
} ENVPOINT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int version;
|
||||
int channels;
|
||||
int start_point;
|
||||
int num_points;
|
||||
int name;
|
||||
} MAPITEM_ENVELOPE;
|
||||
|
||||
// float to fixed
|
||||
inline int f2fx(float v) { return (int)(v*(float)(1<<10)); }
|
||||
inline float fx2f(int v) { return v*(1.0f/(1<<10)); }
|
||||
|
|
|
@ -133,7 +133,9 @@ public:
|
|||
int gametype;
|
||||
gameobject();
|
||||
|
||||
void do_team_wincheck();
|
||||
void do_team_score_wincheck();
|
||||
void do_player_score_wincheck();
|
||||
|
||||
void do_warmup(int seconds);
|
||||
|
||||
void startround();
|
||||
|
|
|
@ -289,7 +289,40 @@ int gameobject::getteam(int notthisid)
|
|||
return numplayers[0] > numplayers[1] ? 1 : 0;
|
||||
}
|
||||
|
||||
void gameobject::do_team_wincheck()
|
||||
void gameobject::do_player_score_wincheck()
|
||||
{
|
||||
if(game_over_tick == -1 && !warmup)
|
||||
{
|
||||
// gather some stats
|
||||
int topscore = 0;
|
||||
int topscore_count = 0;
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(players[i].client_id != -1)
|
||||
{
|
||||
if(players[i].score > topscore)
|
||||
{
|
||||
topscore = players[i].score;
|
||||
topscore_count = 1;
|
||||
}
|
||||
else if(players[i].score == topscore)
|
||||
topscore_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// check score win condition
|
||||
if((config.sv_scorelimit > 0 && topscore >= config.sv_scorelimit) ||
|
||||
(config.sv_timelimit > 0 && (server_tick()-round_start_tick) >= config.sv_timelimit*server_tickspeed()*60))
|
||||
{
|
||||
if(topscore_count == 1)
|
||||
endround();
|
||||
else
|
||||
sudden_death = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gameobject::do_team_score_wincheck()
|
||||
{
|
||||
if(game_over_tick == -1 && !warmup)
|
||||
{
|
||||
|
|
|
@ -62,7 +62,7 @@ void gameobject_ctf::tick()
|
|||
{
|
||||
gameobject::tick();
|
||||
|
||||
do_team_wincheck();
|
||||
do_team_score_wincheck();
|
||||
|
||||
// do flags
|
||||
for(int fi = 0; fi < 2; fi++)
|
||||
|
|
|
@ -5,38 +5,6 @@
|
|||
|
||||
void gameobject_dm::tick()
|
||||
{
|
||||
if(game_over_tick == -1)
|
||||
{
|
||||
// game is running
|
||||
|
||||
// gather some stats
|
||||
int topscore = 0;
|
||||
int topscore_count = 0;
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(players[i].client_id != -1)
|
||||
{
|
||||
if(players[i].score > topscore)
|
||||
{
|
||||
topscore = players[i].score;
|
||||
topscore_count = 1;
|
||||
}
|
||||
else if(players[i].score == topscore)
|
||||
topscore_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// check score win condition
|
||||
if((config.sv_scorelimit > 0 && topscore >= config.sv_scorelimit) ||
|
||||
(config.sv_timelimit > 0 && (server_tick()-round_start_tick) >= config.sv_timelimit*server_tickspeed()*60))
|
||||
{
|
||||
if(topscore_count == 1)
|
||||
endround();
|
||||
else
|
||||
sudden_death = 1;
|
||||
}
|
||||
}
|
||||
|
||||
do_player_score_wincheck();
|
||||
gameobject::tick();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ gameobject_tdm::gameobject_tdm()
|
|||
is_teamplay = true;
|
||||
}
|
||||
|
||||
|
||||
int gameobject_tdm::on_player_death(class player *victim, class player *killer, int weapon)
|
||||
{
|
||||
gameobject::on_player_death(victim, killer, weapon);
|
||||
|
@ -26,7 +25,6 @@ int gameobject_tdm::on_player_death(class player *victim, class player *killer,
|
|||
|
||||
void gameobject_tdm::tick()
|
||||
{
|
||||
do_team_wincheck();
|
||||
|
||||
do_team_score_wincheck();
|
||||
gameobject::tick();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue