diff options
| author | Simon Robertshaw <simon@hardwired.org.uk> | 2012-01-17 20:46:06 (GMT) |
|---|---|---|
| committer | Simon Robertshaw <simon@hardwired.org.uk> | 2012-01-17 20:46:06 (GMT) |
| commit | 4a60b97c700c2f1843b7e99313554cb89fb5da4e (patch) | |
| tree | 3b33ef6f74a4e8a4ff5968a81b9c4c429ccaa7c6 /src | |
| parent | 6273089bf486bf46ad325d72c7290ebb272bd3d8 (diff) | |
| download | powder-4a60b97c700c2f1843b7e99313554cb89fb5da4e.zip powder-4a60b97c700c2f1843b7e99313554cb89fb5da4e.tar.gz | |
Some minor changes
Diffstat (limited to 'src')
153 files changed, 9495 insertions, 677 deletions
diff --git a/src/Air.h b/src/Air.h new file mode 100644 index 0000000..8e4dc25 --- /dev/null +++ b/src/Air.h @@ -0,0 +1,33 @@ +#ifndef AIR_H +#define AIR_H +#include "Config.h" + +class Simulation; + +class Air +{ +public: + int airMode; + //Arrays from the simulation + unsigned char (*bmap)[XRES/CELL]; + unsigned char (*emap)[XRES/CELL]; + float (*fvx)[XRES/CELL]; + float (*fvy)[XRES/CELL]; + // + float vx[YRES/CELL][XRES/CELL]; + float ovx[YRES/CELL][XRES/CELL]; + float vy[YRES/CELL][XRES/CELL]; + float ovy[YRES/CELL][XRES/CELL]; + float pv[YRES/CELL][XRES/CELL]; + float opv[YRES/CELL][XRES/CELL]; + float hv[YRES/CELL][XRES/CELL]; + float ohv[YRES/CELL][XRES/CELL]; // Ambient Heat + unsigned char bmap_blockair[YRES/CELL][XRES/CELL]; + float kernel[9]; + void make_kernel(void); + void update_airh(void); + void update_air(void); + Air(); +}; + +#endif diff --git a/src/Config.h b/src/Config.h new file mode 100644 index 0000000..4cb2da3 --- /dev/null +++ b/src/Config.h @@ -0,0 +1,146 @@ +/* + * Config.h + * + * Created on: Jan 5, 2012 + * Author: Simon + */ + +//#ifndef CONFIG_H_ +//#define CONFIG_H_ + + +#ifdef WIN32 +#define PATH_SEP "\\" +#else +#define PATH_SEP "/" +#endif + +//VersionInfoStart +#define SAVE_VERSION 71 +#define MINOR_VERSION 0 +#define BETA +#define BUILD_NUM 133 +//VersionInfoEnd + +#define IDENT_VERSION "G" //Change this if you're not Simon! It should be a single letter + +#define MTOS_EXPAND(str) #str +#define MTOS(str) MTOS_EXPAND(str) + +#define SERVER "powdertoy.co.uk" +#define SCRIPTSERVER "powdertoy.co.uk" + +#define LOCAL_SAVE_DIR "Saves" + +#define APPDATA_SUBDIR "\\HardWIRED" + +#define THUMB_CACHE_SIZE 256 + +#ifndef M_PI +#define M_PI 3.14159265f +#endif +#ifndef M_GRAV +#define M_GRAV 6.67300e-1 +#endif + +#define IMGCONNS 3 +#define TIMEOUT 100 +#define HTTP_TIMEOUT 10 + +#ifdef RENDERER +#define MENUSIZE 0 +#define BARSIZE 0 +#else +#define MENUSIZE 40 +#define BARSIZE 17 +#endif +#define XRES 612 +#define YRES 384 +#define NPART XRES*YRES + +#define XCNTR 306 +#define YCNTR 192 + +#define MAX_DISTANCE sqrt(pow(XRES, 2)+pow(YRES, 2)) + +#define GRAV_DIFF + +#define MAXSIGNS 16 +#define TAG_MAX 256 + +#define ZSIZE_D 16 +#define ZFACTOR_D 8 +extern unsigned char ZFACTOR; +extern unsigned char ZSIZE; + +#define CELL 4 +#define ISTP (CELL/2) +#define CFDS (4.0f/CELL) + +#define AIR_TSTEPP 0.3f +#define AIR_TSTEPV 0.4f +#define AIR_VADV 0.3f +#define AIR_VLOSS 0.999f +#define AIR_PLOSS 0.9999f + +#define GRID_X 5 +#define GRID_Y 4 +#define GRID_P 3 +#define GRID_S 6 +#define GRID_Z 3 + +#define CATALOGUE_X 4 +#define CATALOGUE_Y 3 +#define CATALOGUE_S 6 +#define CATALOGUE_Z 3 + +#define STAMP_MAX 240 + +#define SAVE_OPS + +#define NGOL 25 +#define NGOLALT 24 //NGOL should be 24, but use this var until I find out why + +#define CIRCLE_BRUSH 0 +#define SQUARE_BRUSH 1 +#define TRI_BRUSH 2 +#define BRUSH_NUM 3 + +#define SURF_RANGE 10 +#define NORMAL_MIN_EST 3 +#define NORMAL_INTERP 20 +#define NORMAL_FRAC 16 + +#define REFRACT 0x80000000 + +/* heavy flint glass, for awesome refraction/dispersion + this way you can make roof prisms easily */ +#define GLASS_IOR 1.9 +#define GLASS_DISP 0.07 + +#ifdef WIN32 +#define strcasecmp stricmp +#endif +#if defined(WIN32) && !defined(__GNUC__) +#define fmin min +#define fminf min +#define fmax max +#define fmaxf max +#endif + +#if defined(WIN32) && !defined(__GNUC__) +#define TPT_INLINE _inline +#else +#define TPT_INLINE inline +#endif + +#define SDEUT +//#define REALHEAT + +#define DEBUG_PARTS 0x0001 +#define DEBUG_PARTCOUNT 0x0002 +#define DEBUG_DRAWTOOL 0x0004 +#define DEBUG_PERFORMANCE_CALC 0x0008 +#define DEBUG_PERFORMANCE_FRAME 0x0010 + +//#endif /* CONFIG_H_ */ diff --git a/src/Console.h b/src/Console.h new file mode 100644 index 0000000..657f935 --- /dev/null +++ b/src/Console.h @@ -0,0 +1,48 @@ +#ifndef CONSOLE_H +#define CONSOLE_H + +#include <string> +#include <vector> + +#include "interface/Sandbox.h" +#include "Simulation.h" + +class ConsoleCommand +{ +private: + std::string * command; + int returnStatus; + std::string * returnString; +public: + void SetCommand(std::string * command); + void SetError(std::string * error); + std::string * GetCommand(); + std::string * GetError(); + ConsoleCommand(); + ConsoleCommand(std::string * command, int returnStatus, std::string * returnString = new std::string("")); +}; + +class Console +{ +private: + bool sound_enable; + bool file_script; + std::vector<ConsoleCommand> * previousCommands; + std::string * lastError; + ui::Sandbox * sandbox; + Simulation * sim; +public: + virtual void Tick(float * dt); + int ParseType(char * txt); + int ParsePartref(char * txt); + int ParseCoords(char * coords, int *x, int *y); + virtual void ConsoleShown(); + virtual void ConsoleHidden(); + virtual int ProcessCommand(char * console); + virtual std::string * GetLastError(); + virtual std::vector<ConsoleCommand> * GetPreviousCommands(); + Console(ui::Sandbox * sandbox); + virtual ~Console(); +}; + +#endif // CONSOLE_H diff --git a/src/Element.h b/src/Element.h new file mode 100644 index 0000000..449bf51 --- /dev/null +++ b/src/Element.h @@ -0,0 +1,14 @@ +#ifndef ELEMENT_H +#define ELEMENT_H +// This header should be included by all files in src/elements/ + +#include <math.h> +#include "Simulation.h" +#include "Renderer.h" +#include "ElementFunctions.h" +//#include "powder.h" +#include "Gravity.h" +#include "Misc.h" +#include "ElementGraphics.h" + +#endif diff --git a/src/ElementFunctions.h b/src/ElementFunctions.h new file mode 100644 index 0000000..ef80b6f --- /dev/null +++ b/src/ElementFunctions.h @@ -0,0 +1,168 @@ +/* + * ElementFunctions.h + * + * Created on: Jan 5, 2012 + * Author: Simon + */ + +#ifndef ELEMENTFUNCTIONS_H_ +#define ELEMENTFUNCTIONS_H_ +#include "Elements.h" + +int update_ACID(UPDATE_FUNC_ARGS); +int update_ANAR(UPDATE_FUNC_ARGS); +int update_AMTR(UPDATE_FUNC_ARGS); +int update_ARAY(UPDATE_FUNC_ARGS); +int update_BCLN(UPDATE_FUNC_ARGS); +int update_BCOL(UPDATE_FUNC_ARGS); +int update_BMTL(UPDATE_FUNC_ARGS); +int update_BRMT(UPDATE_FUNC_ARGS); +int update_BOMB(UPDATE_FUNC_ARGS); +int update_BOYL(UPDATE_FUNC_ARGS); +int update_BTRY(UPDATE_FUNC_ARGS); +int update_C5(UPDATE_FUNC_ARGS); +int update_CLNE(UPDATE_FUNC_ARGS); +int update_COAL(UPDATE_FUNC_ARGS); +int update_DEUT(UPDATE_FUNC_ARGS); +int update_DSTW(UPDATE_FUNC_ARGS); +int update_FOG(UPDATE_FUNC_ARGS); +int update_FRZW(UPDATE_FUNC_ARGS); +int update_FRZZ(UPDATE_FUNC_ARGS); +int update_FSEP(UPDATE_FUNC_ARGS); +int update_FUSE(UPDATE_FUNC_ARGS); +int update_FIRW(UPDATE_FUNC_ARGS); +int update_FWRK(UPDATE_FUNC_ARGS); +int update_GLAS(UPDATE_FUNC_ARGS); +int update_GLOW(UPDATE_FUNC_ARGS); +int update_GOO(UPDATE_FUNC_ARGS); +int update_HSWC(UPDATE_FUNC_ARGS); +int update_IRON(UPDATE_FUNC_ARGS); +int update_ICEI(UPDATE_FUNC_ARGS); +int update_ISZ(UPDATE_FUNC_ARGS); +int update_LCRY(UPDATE_FUNC_ARGS); +int update_MORT(UPDATE_FUNC_ARGS); +int update_NEUT(UPDATE_FUNC_ARGS); +int update_NPTCT(UPDATE_FUNC_ARGS); +int update_PCLN(UPDATE_FUNC_ARGS); +int update_PHOT(UPDATE_FUNC_ARGS); +int update_PIPE(UPDATE_FUNC_ARGS); +int update_PLNT(UPDATE_FUNC_ARGS); +int update_PLUT(UPDATE_FUNC_ARGS); +int update_PRTI(UPDATE_FUNC_ARGS); +int update_PRTO(UPDATE_FUNC_ARGS); +int update_PYRO(UPDATE_FUNC_ARGS); +int update_PUMP(UPDATE_FUNC_ARGS); +int update_QRTZ(UPDATE_FUNC_ARGS); +int update_RIME(UPDATE_FUNC_ARGS); +int update_SHLD1(UPDATE_FUNC_ARGS); +int update_SHLD2(UPDATE_FUNC_ARGS); +int update_SHLD3(UPDATE_FUNC_ARGS); +int update_SHLD4(UPDATE_FUNC_ARGS); +int update_SING(UPDATE_FUNC_ARGS); +int update_SLTW(UPDATE_FUNC_ARGS); +int update_SPAWN(UPDATE_FUNC_ARGS); +int update_SPAWN2(UPDATE_FUNC_ARGS); +int update_SPNG(UPDATE_FUNC_ARGS); +int update_SPRK(UPDATE_FUNC_ARGS); +int update_STKM(UPDATE_FUNC_ARGS); +int update_STKM2(UPDATE_FUNC_ARGS); +int update_SWCH(UPDATE_FUNC_ARGS); +int update_THDR(UPDATE_FUNC_ARGS); +int update_THRM(UPDATE_FUNC_ARGS); +int update_URAN(UPDATE_FUNC_ARGS); +int update_VINE(UPDATE_FUNC_ARGS); +int update_WARP(UPDATE_FUNC_ARGS); +int update_WATR(UPDATE_FUNC_ARGS); +int update_WIFI(UPDATE_FUNC_ARGS); +int update_WTRV(UPDATE_FUNC_ARGS); +int update_YEST(UPDATE_FUNC_ARGS); +int update_SOAP(UPDATE_FUNC_ARGS); +int update_O2(UPDATE_FUNC_ARGS); +int update_H2(UPDATE_FUNC_ARGS); +int update_NBHL(UPDATE_FUNC_ARGS); +int update_NWHL(UPDATE_FUNC_ARGS); +int update_MERC(UPDATE_FUNC_ARGS); +int update_PBCN(UPDATE_FUNC_ARGS); +int update_GPMP(UPDATE_FUNC_ARGS); +int update_CLST(UPDATE_FUNC_ARGS); +int update_DLAY(UPDATE_FUNC_ARGS); +int update_WIRE(UPDATE_FUNC_ARGS); +int update_GBMB(UPDATE_FUNC_ARGS); +int update_CO2(UPDATE_FUNC_ARGS); +int update_CBNW(UPDATE_FUNC_ARGS); +int update_STOR(UPDATE_FUNC_ARGS); +int update_BIZR(UPDATE_FUNC_ARGS); +int update_PVOD(UPDATE_FUNC_ARGS); +int update_CONV(UPDATE_FUNC_ARGS); +int update_CAUS(UPDATE_FUNC_ARGS); +int update_DEST(UPDATE_FUNC_ARGS); +int update_EMP(UPDATE_FUNC_ARGS); +int update_LIGH(UPDATE_FUNC_ARGS); +int update_FIGH(UPDATE_FUNC_ARGS); +int update_ELEC(UPDATE_FUNC_ARGS); +int update_ACEL(UPDATE_FUNC_ARGS); +int update_DCEL(UPDATE_FUNC_ARGS); +int update_BANG(UPDATE_FUNC_ARGS); +int update_IGNT(UPDATE_FUNC_ARGS); +int update_MISC(UPDATE_FUNC_ARGS); +int update_legacy_PYRO(UPDATE_FUNC_ARGS); +int update_legacy_all(UPDATE_FUNC_ARGS); +int run_stickman(playerst* playerp, UPDATE_FUNC_ARGS); +void STKM_init_legs(Simulation * sim, playerst* playerp, int i); +void STKM_interact(Simulation * sim, playerst* playerp, int i, int x, int y); + + +int graphics_FIRE(GRAPHICS_FUNC_ARGS); +int graphics_SMKE(GRAPHICS_FUNC_ARGS); +int graphics_PLSM(GRAPHICS_FUNC_ARGS); +int graphics_DEUT(GRAPHICS_FUNC_ARGS); +int graphics_PHOT(GRAPHICS_FUNC_ARGS); +int graphics_NEUT(GRAPHICS_FUNC_ARGS); +int graphics_LAVA(GRAPHICS_FUNC_ARGS); +int graphics_SPRK(GRAPHICS_FUNC_ARGS); +int graphics_QRTZ(GRAPHICS_FUNC_ARGS); +int graphics_CLST(GRAPHICS_FUNC_ARGS); +int graphics_CBNW(GRAPHICS_FUNC_ARGS); +int graphics_SPNG(GRAPHICS_FUNC_ARGS); +int graphics_LIFE(GRAPHICS_FUNC_ARGS); +int graphics_DUST(GRAPHICS_FUNC_ARGS); +int graphics_GRAV(GRAPHICS_FUNC_ARGS); +int graphics_WIFI(GRAPHICS_FUNC_ARGS); +int graphics_PRTI(GRAPHICS_FUNC_ARGS); +int graphics_PRTO(GRAPHICS_FUNC_ARGS); +int graphics_BIZR(GRAPHICS_FUNC_ARGS); +int graphics_PIPE(GRAPHICS_FUNC_ARGS); +int graphics_INVS(GRAPHICS_FUNC_ARGS); +int graphics_ACID(GRAPHICS_FUNC_ARGS); +int graphics_FILT(GRAPHICS_FUNC_ARGS); +int graphics_BRAY(GRAPHICS_FUNC_ARGS); +int graphics_SWCH(GRAPHICS_FUNC_ARGS); +int graphics_THDR(GRAPHICS_FUNC_ARGS); +int graphics_GLOW(GRAPHICS_FUNC_ARGS); +int graphics_LCRY(GRAPHICS_FUNC_ARGS); +int graphics_PCLN(GRAPHICS_FUNC_ARGS); +int graphics_PBCN(GRAPHICS_FUNC_ARGS); +int graphics_DLAY(GRAPHICS_FUNC_ARGS); +int graphics_HSWC(GRAPHICS_FUNC_ARGS); +int graphics_PVOD(GRAPHICS_FUNC_ARGS); +int graphics_STOR(GRAPHICS_FUNC_ARGS); +int graphics_PUMP(GRAPHICS_FUNC_ARGS); +int graphics_GPMP(GRAPHICS_FUNC_ARGS); +int graphics_HFLM(GRAPHICS_FUNC_ARGS); +int graphics_FIRW(GRAPHICS_FUNC_ARGS); +int graphics_BOMB(GRAPHICS_FUNC_ARGS); +int graphics_GBMB(GRAPHICS_FUNC_ARGS); +int graphics_COAL(GRAPHICS_FUNC_ARGS); +int graphics_STKM(GRAPHICS_FUNC_ARGS); +int graphics_STKM2(GRAPHICS_FUNC_ARGS); +int graphics_DEST(GRAPHICS_FUNC_ARGS); +int graphics_EMP(GRAPHICS_FUNC_ARGS); +int graphics_LIGH(GRAPHICS_FUNC_ARGS); +int graphics_FIGH(GRAPHICS_FUNC_ARGS); +int graphics_ELEC(GRAPHICS_FUNC_ARGS); +int graphics_WIRE(GRAPHICS_FUNC_ARGS); +int graphics_ACEL(GRAPHICS_FUNC_ARGS); +int graphics_DCEL(GRAPHICS_FUNC_ARGS); +int graphics_DEFAULT(GRAPHICS_FUNC_ARGS); + +#endif /* ELEMENTFUNCTIONS_H_ */ diff --git a/src/ElementGraphics.h b/src/ElementGraphics.h new file mode 100644 index 0000000..a880e71 --- /dev/null +++ b/src/ElementGraphics.h @@ -0,0 +1,52 @@ +#ifndef PGRAPHICS_H +#define PGRAPHICS_H + +#define PMODE 0x00000FFF +#define PMODE_NONE 0x00000000 +#define PMODE_FLAT 0x00000001 +#define PMODE_BLOB 0x00000002 +#define PMODE_BLUR 0x00000004 +#define PMODE_GLOW 0x00000008 +#define PMODE_SPARK 0x00000010 +#define PMODE_FLARE 0x00000020 +#define PMODE_LFLARE 0x00000040 +#define PMODE_ADD 0x00000080 +#define PMODE_BLEND 0x00000100 +#define PSPEC_STICKMAN 0x00000200 + +#define OPTIONS 0x0000F000 +#define NO_DECO 0x00001000 +#define DECO_FIRE 0x00002000 + +#define FIREMODE 0x00FF0000 +#define FIRE_ADD 0x00010000 +#define FIRE_BLEND 0x00020000 + +#define EFFECT 0xFF000000 +#define EFFECT_GRAVIN 0x01000000 +#define EFFECT_GRAVOUT 0x02000000 + +#define RENDER_EFFE OPTIONS | PSPEC_STICKMAN | EFFECT | PMODE_SPARK | PMODE_FLARE | PMODE_LFLARE +#define RENDER_FIRE OPTIONS | PSPEC_STICKMAN | PMODE_FLAT | PMODE_ADD | PMODE_BLEND | FIREMODE +#define RENDER_GLOW OPTIONS | PSPEC_STICKMAN | PMODE_FLAT | PMODE_GLOW | PMODE_ADD | PMODE_BLEND +#define RENDER_BLUR OPTIONS | PSPEC_STICKMAN | PMODE_FLAT | PMODE_BLUR | PMODE_ADD | PMODE_BLEND +#define RENDER_BLOB OPTIONS | PSPEC_STICKMAN | PMODE_FLAT | PMODE_BLOB | PMODE_ADD | PMODE_BLEND +#define RENDER_BASC OPTIONS | PSPEC_STICKMAN | PMODE_FLAT | PMODE_ADD | PMODE_BLEND +#define RENDER_NONE OPTIONS | PSPEC_STICKMAN | PMODE_FLAT + +#define COLOUR_HEAT 0x00000001 +#define COLOUR_LIFE 0x00000002 +#define COLOUR_GRAD 0x00000004 + +#define COLOUR_DEFAULT 0x00000000 + +#define DISPLAY_AIRC 0x00000001 +#define DISPLAY_AIRP 0x00000002 +#define DISPLAY_AIRV 0x00000004 +#define DISPLAY_AIRH 0x00000008 +#define DISPLAY_AIR 0x0000000F +#define DISPLAY_WARP 0x00000010 +#define DISPLAY_PERS 0x00000020 +#define DISPLAY_EFFE 0x00000040 + +#endif diff --git a/src/Elements.h b/src/Elements.h new file mode 100644 index 0000000..204460c --- /dev/null +++ b/src/Elements.h @@ -0,0 +1,280 @@ +/* + * Elements.h + * + * Created on: Jan 5, 2012 + * Author: Simon + */ + +//#ifndef ELEMENTS_H_ +//#define ELEMENTS_H_ + +//#include "Config.h" +//#include "Simulation.h" + +#define IPL -257.0f +#define IPH 257.0f +#define ITL MIN_TEMP-1 +#define ITH MAX_TEMP+1 +// no transition (PT_NONE means kill part) +#define NT -1 +// special transition - lava ctypes etc need extra code, which is only found and run if ST is given +#define ST PT_NUM + +#define R_TEMP 22 +#define MAX_TEMP 9999 +#define MIN_TEMP 0 +#define O_MAX_TEMP 3500 +#define O_MIN_TEMP -273 + +#define TYPE_PART 0x00001 //1 Powders +#define TYPE_LIQUID 0x00002 //2 Liquids +#define TYPE_SOLID 0x00004 //4 Solids +#define TYPE_GAS 0x00008 //8 Gasses (Includes plasma) +#define TYPE_ENERGY 0x00010 //16 Energy (Thunder, Light, Neutrons etc.) +#define PROP_CONDUCTS 0x00020 //32 Conducts electricity +#define PROP_BLACK 0x00040 //64 Absorbs Photons (not currently implemented or used, a photwl attribute might be better) +#define PROP_NEUTPENETRATE 0x00080 //128 Penetrated by neutrons +#define PROP_NEUTABSORB 0x00100 //256 Absorbs neutrons, reflect is default (not currently implemented or used) +#define PROP_NEUTPASS 0x00200 //512 Neutrons pass through, such as with glass +#define PROP_DEADLY 0x00400 //1024 Is deadly for stickman (not currently implemented or used) +#define PROP_HOT_GLOW 0x00800 //2048 Hot Metal Glow +#define PROP_LIFE 0x01000 //4096 Is a GoL type +#define PROP_RADIOACTIVE 0x02000 //8192 Radioactive +#define PROP_LIFE_DEC 0x04000 //2^14 Life decreases by one every frame if > zero +#define PROP_LIFE_KILL 0x08000 //2^15 Kill when life value is <= zero +#define PROP_LIFE_KILL_DEC 0x10000 //2^16 Kill when life value is decremented to <= zero +#define PROP_SPARKSETTLE 0x20000 //2^17 Allow Sparks/Embers to settle + +#define FLAG_STAGNANT 1 + +#define ST_NONE 0 +#define ST_SOLID 1 +#define ST_LIQUID 2 +#define ST_GAS 3 + +#define UPDATE_FUNC_ARGS Simulation* sim, int i, int x, int y, int surround_space, int nt, Particle *parts, int pmap[YRES][XRES] +// to call another update function with same arguments: +#define UPDATE_FUNC_SUBCALL_ARGS sim, i, x, y, surround_space, nt, parts, pmap + +#define GRAPHICS_FUNC_ARGS Renderer * ren, Particle *cpart, int nx, int ny, int *pixel_mode, int* cola, int *colr, int *colg, int *colb, int *firea, int *firer, int *fireg, int *fireb +#define GRAPHICS_FUNC_SUBCALL_ARGS ren, cpart, nx, ny, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, fireb + +#define UI_WALLSTART 222 +#define UI_ACTUALSTART 122 +#define UI_WALLCOUNT 25 + +#define WL_WALLELEC 122 +#define WL_EWALL 123 +#define WL_DETECT 124 +#define WL_STREAM 125 +#define WL_SIGN 126 +#define WL_FAN 127 +#define WL_FANHELPER 255 +#define WL_ALLOWLIQUID 128 +#define WL_DESTROYALL 129 +#define WL_ERASE 130 +#define WL_WALL 131 +#define WL_ALLOWAIR 132 +#define WL_ALLOWSOLID 133 +#define WL_ALLOWALLELEC 134 +#define WL_EHOLE 135 + +#define SPC_AIR 236 +#define SPC_HEAT 237 +#define SPC_COOL 238 +#define SPC_VACUUM 239 +#define SPC_WIND 241 +#define SPC_PGRV 243 +#define SPC_NGRV 244 +#define SPC_PROP 246 + +#define WL_ALLOWGAS 140 +#define WL_GRAV 142 +#define WL_ALLOWENERGY 145 + +#define NGT_GOL 0 +#define NGT_HLIF 1 +#define NGT_ASIM 2 +#define NGT_2x2 3 +#define NGT_DANI 4 +#define NGT_AMOE 5 +#define NGT_MOVE 6 +#define NGT_PGOL 7 +#define NGT_DMOE 8 +#define NGT_34 9 +#define NGT_LLIF 10 +#define NGT_STAN 11 +#define NGT_SEED 12 +#define NGT_MAZE 13 +#define NGT_COAG 14 +#define NGT_WALL 15 +#define NGT_GNAR 16 +#define NGT_REPL 17 +#define NGT_MYST 18 +#define NGT_LOTE 19 +#define NGT_FRG2 20 +#define NGT_STAR 21 +#define NGT_FROG 22 +#define NGT_BRAN 23 + +#define PT_NONE 0 +#define PT_DUST 1 +#define PT_WATR 2 +#define PT_OIL 3 +#define PT_FIRE 4 +#define PT_STNE 5 +#define PT_LAVA 6 +#define PT_GUNP 7 +#define PT_NITR 8 +#define PT_CLNE 9 +#define PT_GAS 10 +#define PT_PLEX 11 +#define PT_GOO 12 +#define PT_ICEI 13 +#define PT_METL 14 +#define PT_SPRK 15 +#define PT_SNOW 16 +#define PT_WOOD 17 +#define PT_NEUT 18 +#define PT_PLUT 19 +#define PT_PLNT 20 +#define PT_ACID 21 +#define PT_VOID 22 +#define PT_WTRV 23 +#define PT_CNCT 24 +#define PT_DSTW 25 +#define PT_SALT 26 +#define PT_SLTW 27 +#define PT_DMND 28 +#define PT_BMTL 29 +#define PT_BRMT 30 +#define PT_PHOT 31 +#define PT_URAN 32 +#define PT_WAX 33 +#define PT_MWAX 34 +#define PT_PSCN 35 +#define PT_NSCN 36 +#define PT_LNTG 37 +#define PT_INSL 38 +#define PT_BHOL 39 +#define PT_WHOL 40 +#define PT_RBDM 41 +#define PT_LRBD 42 +#define PT_NTCT 43 +#define PT_SAND 44 +#define PT_GLAS 45 +#define PT_PTCT 46 +#define PT_BGLA 47 +#define PT_THDR 48 +#define PT_PLSM 49 +#define PT_ETRD 50 +#define PT_NICE 51 +#define PT_NBLE 52 +#define PT_BTRY 53 +#define PT_LCRY 54 +#define PT_STKM 55 +#define PT_SWCH 56 +#define PT_SMKE 57 +#define PT_DESL 58 +#define PT_COAL 59 +#define PT_LO2 60 +#define PT_O2 61 +#define PT_INWR 62 +#define PT_YEST 63 +#define PT_DYST 64 +#define PT_THRM 65 +#define PT_GLOW 66 +#define PT_BRCK 67 +#define PT_HFLM 68 +#define PT_FIRW 69 +#define PT_FUSE 70 +#define PT_FSEP 71 +#define PT_AMTR 72 +#define PT_BCOL 73 +#define PT_PCLN 74 +#define PT_HSWC 75 +#define PT_IRON 76 +#define PT_MORT 77 +#define PT_LIFE 78 +#define PT_DLAY 79 +#define PT_CO2 80 +#define PT_DRIC 81 +#define PT_CBNW 82 +#define PT_STOR 83 +#define PT_PVOD 84 +#define PT_CONV 85 +#define PT_CAUS 86 + +#define PT_LIGH 87 +#define PT_TESC 88 +#define PT_DEST 89 + +#define PT_SPNG 90 +#define PT_RIME 91 +#define PT_FOG 92 +#define PT_BCLN 93 +#define PT_LOVE 94 +#define PT_DEUT 95 +#define PT_WARP 96 +#define PT_PUMP 97 +#define PT_FWRK 98 +#define PT_PIPE 99 +#define PT_FRZZ 100 +#define PT_FRZW 101 +#define PT_GRAV 102 +#define PT_BIZR 103 +#define PT_BIZRG 104 +#define PT_BIZRS 105 +#define PT_INST 106 +#define PT_ISOZ 107 +#define PT_ISZS 108 +#define PT_PRTI 109 +#define PT_PRTO 110 +#define PT_PSTE 111 +#define PT_PSTS 112 +#define PT_ANAR 113 +#define PT_VINE 114 +#define PT_INVIS 115 +#define PT_EQUALVEL 116 //all particles equal their velocities +#define PT_SPAWN2 117 +#define PT_SPAWN 118 +#define PT_SHLD1 119 +#define PT_SHLD2 120 +#define PT_SHLD3 121 +#define PT_SHLD4 122 +#define PT_LOLZ 123 +#define PT_WIFI 124 +#define PT_FILT 125 +#define PT_ARAY 126 +#define PT_BRAY 127 +#define PT_STKM2 128 +#define PT_BOMB 129 +#define PT_C5 130 +#define PT_SING 131 +#define PT_QRTZ 132 +#define PT_PQRT 133 +#define PT_EMP 134 +#define PT_BREC 135 +#define PT_ELEC 136 +#define PT_ACEL 137 +#define PT_DCEL 138 +#define PT_BANG 139 +#define PT_IGNT 140 +#define PT_BOYL 141 + +#define OLD_PT_WIND 147 +#define PT_H2 148 +#define PT_SOAP 149 +#define PT_NBHL 150 +#define PT_NWHL 151 +#define PT_MERC 152 +#define PT_PBCN 153 +#define PT_GPMP 154 +#define PT_CLST 155 +#define PT_WIRE 156 +#define PT_GBMB 157 +#define PT_FIGH 158 +#define PT_NUM 159 + + +//#endif /* ELEMENTS_H_ */ diff --git a/src/GameSession.cpp b/src/GameSession.cpp deleted file mode 100644 index 364f268..0000000 --- a/src/GameSession.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "GameSession.h" - -GameSession::GameSession() -{ - //Boop -} diff --git a/src/Global.cpp b/src/Global.cpp index 7bf28f0..c1e0559 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -1,5 +1,6 @@ -#include "Global.h" +/*#include "Global.h" Global::Global(){ } +*/ diff --git a/src/Global.h b/src/Global.h new file mode 100644 index 0000000..ceff38e --- /dev/null +++ b/src/Global.h @@ -0,0 +1,14 @@ +#ifndef GAMESESSION_H +#define GAMESESSION_H + +#include "Singleton.h" +#include "Graphics.h" + +/*class Global : public Singleton<Global> +{ +public: + Graphics * g; + Global(); +};*/ + +#endif // GAMESESSION_H diff --git a/src/Graphics.h b/src/Graphics.h new file mode 100644 index 0000000..6cd5b36 --- /dev/null +++ b/src/Graphics.h @@ -0,0 +1,172 @@ +#ifndef GRAPHICS_H +#define GRAPHICS_H + +#include <SDL/SDL.h> +#include <string> +#include "Config.h" +//#include "powder.h" + +#ifdef PIX16 +#define PIXELSIZE 2 +#define PIXPACK(x) ((((x)>>8)&0xF800)|(((x)>>5)&0x07E0)|(((x)>>3)&0x001F)) +#define PIXRGB(r,g,b) ((((r)<<8)&0xF800)|(((g)<<3)&0x07E0)|(((b)>>3)&0x001F)) +#define PIXR(x) (((x)>>8)&0xF8) +#define PIXG(x) (((x)>>3)&0xFC) +#define PIXB(x) (((x)<<3)&0xF8) +#else +#define PIXELSIZE 4 +#ifdef PIX32BGR +#define PIXPACK(x) ((((x)>>16)&0x0000FF)|((x)&0x00FF00)|(((x)<<16)&0xFF0000)) +#define PIXRGB(r,g,b) (((b)<<16)|((g)<<8)|((r)))// (((b)<<16)|((g)<<8)|(r)) +#define PIXR(x) ((x)&0xFF) +#define PIXG(x) (((x)>>8)&0xFF) +#define PIXB(x) ((x)>>16) +#else +#ifdef PIX32BGRA +#define PIXPACK(x) ((((x)>>8)&0x0000FF00)|(((x)<<8)&0x00FF0000)|(((x)<<24)&0xFF000000)) +#define PIXRGB(r,g,b) (((b)<<24)|((g)<<16)|((r)<<8)) +#define PIXR(x) (((x)>>8)&0xFF) +#define PIXG(x) (((x)>>16)&0xFF) +#define PIXB(x) (((x)>>24)) +#elif defined(PIX32OGL) +#define PIXPACK(x) (0xFF000000|((x)&0xFFFFFF)) +#define PIXRGB(r,g,b) (0xFF000000|((r)<<16)|((g)<<8)|((b)))// (((b)<<16)|((g)<<8)|(r)) +#define PIXRGBA(r,g,b,a) (((a)<<24)|((r)<<16)|((g)<<8)|((b)))// (((b)<<16)|((g)<<8)|(r)) +#define PIXA(x) (((x)>>24)&0xFF) +#define PIXR(x) (((x)>>16)&0xFF) +#define PIXG(x) (((x)>>8)&0xFF) +#define PIXB(x) ((x)&0xFF) +#else +#define PIXPACK(x) (x) +#define PIXRGB(r,g,b) (((r)<<16)|((g)<<8)|(b)) +#define PIXR(x) ((x)>>16) +#define PIXG(x) (((x)>>8)&0xFF) +#define PIXB(x) ((x)&0xFF) +#endif +#endif +#endif + +#ifdef PIX16 +typedef unsigned short pixel; +#else +typedef unsigned int pixel; +#endif + +/*extern int emp_decor; + +extern unsigned int *render_modes; +extern unsigned int render_mode; +extern unsigned int colour_mode; +extern unsigned int *display_modes; +extern unsigned int display_mode; + +extern SDL_Surface *sdl_scrn; +extern int sdl_scale; + +extern int sandcolour_r; +extern int sandcolour_g; +extern int sandcolour_b; +extern int sandcolour_frame; + +extern unsigned char fire_r[YRES/CELL][XRES/CELL]; +extern unsigned char fire_g[YRES/CELL][XRES/CELL]; +extern unsigned char fire_b[YRES/CELL][XRES/CELL]; + +extern unsigned int fire_alpha[CELL*3][CELL*3]; +extern pixel *pers_bg; + +extern char * flm_data; +extern int flm_data_points; +extern pixel flm_data_colours[]; +extern float flm_data_pos[]; + +extern char * plasma_data; +extern int plasma_data_points; +extern pixel plasma_data_colours[]; +extern float plasma_data_pos[];*/ + +class Graphics +{ +public: + SDL_Surface * sdl_scrn; + pixel *vid; + pixel *render_packed_rgb(void *image, int width, int height, int cmp_size); + static char * generate_gradient(pixel * colours, float * points, int pointcount, int size); + void draw_other(); + void draw_rgba_image(unsigned char *data, int x, int y, float a); + static void *ptif_pack(pixel *src, int w, int h, int *result_size); + static pixel *ptif_unpack(void *datain, int size, int *w, int *h); + static pixel *resample_img_nn(pixel *src, int sw, int sh, int rw, int rh); + static pixel *resample_img(pixel *src, int sw, int sh, int rw, int rh); + static pixel *rescale_img(pixel *src, int sw, int sh, int *qw, int *qh, int f); + //void render_gravlensing(pixel *src, pixel * dst); + //void sdl_blit_1(int x, int y, int w, int h, pixel *src, int pitch); + //void sdl_blit_2(int x, int y, int w, int h, pixel *src, int pitch); + //void sdl_blit(int x, int y, int w, int h, pixel *src, int pitch); + void drawblob(int x, int y, unsigned char cr, unsigned char cg, unsigned char cb); + void draw_tool(int b, int sl, int sr, unsigned pc, unsigned iswall); + //int draw_tool_xy(pixel *vid_buf, int x, int y, int b, unsigned pc); + //void draw_menu(pixel *vid_buf, int i, int hover); + void drawpixel(int x, int y, int r, int g, int b, int a); + int addchar(int x, int y, int c, int r, int g, int b, int a); + int drawchar(int x, int y, int c, int r, int g, int b, int a); + int drawtext(int x, int y, std::string &s, int r, int g, int b, int a); + int drawtext(int x, int y, const char *s, int r, int g, int b, int a); + int drawtext_outline(int x, int y, const char *s, int r, int g, int b, int a, int olr, int olg, int olb, int ola); + int drawtextwrap(int x, int y, int w, const char *s, int r, int g, int b, int a); + void drawrect(int x, int y, int w, int h, int r, int g, int b, int a); + void fillrect(int x, int y, int w, int h, int r, int g, int b, int a); + void clearrect(int x, int y, int w, int h); + void drawdots(int x, int y, int h, int r, int g, int b, int a); + static int textwidth(char *s); + int drawtextmax(int x, int y, int w, char *s, int r, int g, int b, int a); + static int textnwidth(char *s, int n); + static void textnpos(char *s, int n, int w, int *cx, int *cy); + static int textwidthx(char *s, int w); + static int textposxy(char *s, int width, int w, int h); + static int textwrapheight(char *s, int width); + void blendpixel(int x, int y, int r, int g, int b, int a); + void draw_icon(int x, int y, char ch, int flag); + //void draw_air(); + //void draw_grav_zones(pixel *vid); + //void draw_grav(pixel *vid); + void draw_line(int x1, int y1, int x2, int y2, int r, int g, int b, int a); + void addpixel(int x, int y, int r, int g, int b, int a); + void xor_pixel(int x, int y); + void xor_line(int x1, int y1, int x2, int y2); + void xor_rect(int x, int y, int w, int h); + void blend_line(int x1, int y1, int x2, int y2, int r, int g, int b, int a); + //void render_parts(pixel *vid); +// #ifdef OGLR +// void draw_parts_fbo(); +// #endif +// void draw_parts(); +// void draw_walls(pixel *vid); +// void create_decorations(int x, int y, int rx, int ry, int r, int g, int b, int click, int tool); +// void create_decoration(int x, int y, int r, int g, int b, int click, int tool); +// void line_decorations(int x1, int y1, int x2, int y2, int rx, int ry, int r, int g, int b, int click, int tool); +// void box_decorations(int x1, int y1, int x2, int y2, int r, int g, int b, int click, int tool); +// void draw_color_menu(pixel *vid_buf, int i, int hover); + void draw_wavelengths(int x, int y, int h, int wl); + void render_signs(); +// void render_fire(pixel *dst); +// void prepare_alpha(int size, float intensity); + void draw_image(pixel *img, int x, int y, int w, int h, int a); + static void dim_copy(pixel *dst, pixel *src); + static void dim_copy_pers(pixel *dst, pixel *src); + //void render_zoom(pixel *img); + //int render_thumb(void *thumb, int size, int bzip2, pixel *vid_buf, int px, int py, int scl); + //void render_cursor(pixel *vid, int x, int y, int t, int rx, int ry); + //int sdl_open(void); + //int draw_debug_info(pixel* vid, int lm, int lx, int ly, int cx, int cy, int line_x, int line_y); + void Clear(); + void Blit(); + void AttachSDLSurface(SDL_Surface * surface); + #ifdef OGLR + void clearScreen(float alpha); + void ogl_blit(int x, int y, int w, int h, pixel *src, int pitch, int scale); + #endif + Graphics(); +}; + +#endif diff --git a/src/Gravity.h b/src/Gravity.h new file mode 100644 index 0000000..9f36240 --- /dev/null +++ b/src/Gravity.h @@ -0,0 +1,108 @@ +#ifndef GRAVITY_H +#define GRAVITY_H + +#include <pthread.h> +#include "Config.h" +#include "Simulation.h" + +class Simulation; + +struct mask_el { + char *shape; + char shapeout; + void *next; +}; +typedef struct mask_el mask_el; + + +/* + * float *gravmap = NULL;//Maps to be used by the main thread + float *gravp = NULL; + float *gravy = NULL; + float *gravx = NULL; + unsigned *gravmask = NULL; + + float *th_ogravmap = NULL;// Maps to be processed by the gravity thread + float *th_gravmap = NULL; + float *th_gravx = NULL; + float *th_gravy = NULL; + float *th_gravp = NULL; + + int th_gravchanged = 0; + + pthread_t gravthread; + pthread_mutex_t gravmutex; + pthread_cond_t gravcv; + int grav_ready = 0; + int gravthread_done = 0; + */ +class Gravity +{ +private: + unsigned *gravmask; + + float *th_ogravmap; + float *th_gravmap; + float *th_gravx; + float *th_gravy; + float *th_gravp; + + int th_gravchanged; + + pthread_t gravthread; + pthread_mutex_t gravmutex; + pthread_cond_t gravcv; + int grav_ready; + int gravthread_done; + + //Simulation * sim; +public: + float *gravmap; + float *gravp; + float *gravy; + float *gravx; + unsigned char (*bmap)[XRES/CELL]; + int ngrav_enable; + void grav_mask_r(int x, int y, char checkmap[YRES/CELL][XRES/CELL], char shape[YRES/CELL][XRES/CELL], char *shapeout); + void mask_free(mask_el *c_mask_el); + + void gravity_init(); + void gravity_cleanup(); + void gravity_update_async(); + + static void *update_grav_async_helper(void * context); + void update_grav_async(); + + void start_grav_async(); + void stop_grav_async(); + void update_grav(); + void gravity_mask(); + + void bilinear_interpolation(float *src, float *dst, int sw, int sh, int rw, int rh); + + #ifdef GRAVFFT + void grav_fft_init(); + void grav_fft_cleanup(); + #endif + + Gravity(); +}; + +/*extern int ngrav_enable; //Newtonian gravity +extern int gravwl_timeout; +extern int gravityMode;*/ + +/*float *gravmap;//Maps to be used by the main thread +float *gravp; +float *gravy; +float *gravx; +unsigned *gravmask; + +float *th_ogravmap;// Maps to be processed by the gravity thread +float *th_gravmap; +float *th_gravx; +float *th_gravy; +float *th_gravp;*/ + + +#endif diff --git a/src/Misc.h b/src/Misc.h new file mode 100644 index 0000000..c5a61ef --- /dev/null +++ b/src/Misc.h @@ -0,0 +1,108 @@ +#ifndef UTILS_H +#define UTILS_H +#include <stdio.h> +#include <stdlib.h> + +#if defined(WIN32) && !defined(__GNUC__) +#define x86_cpuid(func,af,bf,cf,df) \ + do {\ + __asm mov eax, func\ + __asm cpuid\ + __asm mov af, eax\ + __asm mov bf, ebx\ + __asm mov cf, ecx\ + __asm mov df, edx\ + } while(0) +#else +#define x86_cpuid(func,af,bf,cf,df) \ +__asm__ __volatile ("cpuid":\ + "=a" (af), "=b" (bf), "=c" (cf), "=d" (df) : "a" (func)); +#endif + +static char hex[] = "0123456789ABCDEF"; + +char *exe_name(void); + +//Signum function +int isign(float i); + +unsigned clamp_flt(float f, float min, float max); + +float restrict_flt(float f, float min, float max); + +char *mystrdup(char *s); + +struct strlist +{ + char *str; + struct strlist *next; +}; + +void strlist_add(struct strlist **list, char *str); + +int strlist_find(struct strlist **list, char *str); + +void strlist_free(struct strlist **list); + +void save_presets(int do_update); + +void clean_text(char *text, int vwidth); + +void load_presets(void); + +void save_string(FILE *f, char *str); + +int sregexp(const char *str, char *pattern); + +int load_string(FILE *f, char *str, int max); + +void strcaturl(char *dst, char *src); + +void strappend(char *dst, char *src); + +void *file_load(char *fn, int *size); + +void clipboard_push_text(char * text); + +char * clipboard_pull_text(); + +extern char *clipboard_text; + +int register_extension(); + +int cpu_check(void); + +void HSV_to_RGB(int h,int s,int v,int *r,int *g,int *b); + +void RGB_to_HSV(int r,int g,int b,int *h,int *s,int *v); + +void membwand(void * dest, void * src, size_t destsize, size_t srcsize); +// a b +// c d + +struct matrix2d { + float a,b,c,d; +}; +typedef struct matrix2d matrix2d; + +// column vector +struct vector2d { + float x,y; +}; +typedef struct vector2d vector2d; + +matrix2d m2d_multiply_m2d(matrix2d m1, matrix2d m2); +vector2d m2d_multiply_v2d(matrix2d m, vector2d v); +matrix2d m2d_multiply_float(matrix2d m, float s); +vector2d v2d_multiply_float(vector2d v, float s); + +vector2d v2d_add(vector2d v1, vector2d v2); +vector2d v2d_sub(vector2d v1, vector2d v2); + +matrix2d m2d_new(float me0, float me1, float me2, float me3); +vector2d v2d_new(float x, float y); + +extern vector2d v2d_zero; +extern matrix2d m2d_identity; + +#endif diff --git a/src/PowderToy.cpp b/src/PowderToy.cpp index 1e9630c..cf7d804 100644 --- a/src/PowderToy.cpp +++ b/src/PowderToy.cpp @@ -19,6 +19,9 @@ #include "interface/Point.h" #include "interface/Label.h" +#include "game/GameController.h" +#include "game/GameView.h" + using namespace std; SDL_Surface * SDLOpen() @@ -66,20 +69,24 @@ int main(int argc, char * argv[]) //Simulation * sim = new Simulation(); //ren = new Renderer(g, sim); - Global::Ref().g = new Graphics(); - Global::Ref().g->AttachSDLSurface(SDLOpen()); + ui::Engine::Ref().g = new Graphics(); + ui::Engine::Ref().g->AttachSDLSurface(SDLOpen()); ui::Engine * engine = &ui::Engine::Ref();//new ui::Engine(); - ui::State * engineState = new ui::State(); - ui::Sandbox * sandbox = new ui::Sandbox(); - ui::Button * button = new ui::Button(ui::Point(100, 100), ui::Point(100, 100), std::string("poP")); + //ui::State * engineState = new ui::State(); ui::Label * fpsLabel = new ui::Label(ui::Point(2, 2), ui::Point(200, 14), std::string("FPS: 0")); + //engineState->AddComponent(fpsLabel); engine->Begin(XRES, YRES); - engine->SetState(engineState); +// engine->SetState(engineState); + + GameController * gameController = new GameController(); + engine->ShowWindow(gameController->GetView()); + /*ui::Sandbox * sandbox = new ui::Sandbox(); + ui::Button * button = new ui::Button(ui::Point(100, 100), ui::Point(100, 100), std::string("poP")); engineState->AddComponent(fpsLabel); engineState->AddComponent(sandbox); engineState->AddComponent(button); - engineState->AddComponent(ControlFactory::MainMenu(0, YRES+MENUSIZE-17, XRES+BARSIZE, 16)); + engineState->AddComponent(ControlFactory::MainMenu(0, YRES+MENUSIZE-17, XRES+BARSIZE, 16));*/ SDL_Event event; while(engine->Running()) diff --git a/src/Renderer.h b/src/Renderer.h new file mode 100644 index 0000000..39c8c1a --- /dev/null +++ b/src/Renderer.h @@ -0,0 +1,60 @@ +#ifndef RENDERER_H +#define RENDERER_H + +#include "Config.h" +#include "Simulation.h" +#include "Graphics.h" + +class Simulation; + +class Graphics; + +struct gcache_item +{ + int isready; + int pixel_mode; + int cola, colr, colg, colb; + int firea, firer, fireg, fireb; +}; +typedef struct gcache_item gcache_item; + +class Renderer +{ +public: + //TODO: Vectors! + unsigned int *render_modes; + unsigned int render_mode; + unsigned int colour_mode; + unsigned int *display_modes; + unsigned int display_mode; + // + unsigned char fire_r[YRES/CELL][XRES/CELL]; + unsigned char fire_g[YRES/CELL][XRES/CELL]; + unsigned char fire_b[YRES/CELL][XRES/CELL]; + unsigned int fire_alpha[CELL*3][CELL*3]; + char * flm_data; + char * plasma_data; + int emp_decor; + // + int decorations_enable; + Simulation * sim; + Graphics * g; + gcache_item *graphicscache; + // + void draw_walls(); + void render_signs(); + void render_gravlensing(); + void render_fire(); + void prepare_alpha(int size, float intensity); + void render_parts(); + void draw_grav_zones(); + void draw_air(); + void draw_grav(); + void draw_other(); + void init_display_modes(); + void get_sign_pos(int i, int *x0, int *y0, int *w, int *h); + void prepare_graphicscache(); + Renderer(Graphics * g, Simulation * sim); +}; + +#endif diff --git a/src/Simulation.h b/src/Simulation.h new file mode 100644 index 0000000..b3c51af --- /dev/null +++ b/src/Simulation.h @@ -0,0 +1,241 @@ +/* + * Simulation.h + * + * Created on: Jan 2, 2012 + * Author: Simon + */ + +#ifndef SIMULATION_H_ +#define SIMULATION_H_ +#include <cstring> +#include "Config.h" +#include "Renderer.h" +#include "Graphics.h" +#include "Elements.h" +#include "misc.h" + +#define CHANNELS ((int)(MAX_TEMP-73)/100+2) + +class Simulation; +class Renderer; +class Gravity; +class Air; + +struct Particle +{ + int type; + int life, ctype; + float x, y, vx, vy; + float temp; + float pavg[2]; + int flags; + int tmp; + int tmp2; + unsigned int dcolour; +}; +typedef struct Particle Particle; + +struct sign +{ + int x,y,ju; + char text[256]; +}; +typedef struct sign sign; + +struct part_type +{ + char *name; + pixel pcolors; + float advection; + float airdrag; + float airloss; + float loss; + float collision; + float gravity; + float diffusion; + float hotair; + int falldown; + int flammable; + int explosive; + int meltable; + int hardness; + int menu; + int enabled; + int weight; + int menusection; + float heat; + unsigned char hconduct; + char *descs; + char state; + unsigned int properties; + int (*update_func) (UPDATE_FUNC_ARGS); + int (*graphics_func) (GRAPHICS_FUNC_ARGS); +}; +typedef struct part_type part_type; + +struct part_transition +{ + float plv; // transition occurs if pv is lower than this + int plt; + float phv; // transition occurs if pv is higher than this + int pht; + float tlv; // transition occurs if t is lower than this + int tlt; + float thv; // transition occurs if t is higher than this + int tht; +}; +typedef struct part_transition part_transition; + +struct playerst +{ + char comm; //command cell + char pcomm; //previous command + int elem; //element power + float legs[16]; //legs' positions + float accs[8]; //accelerations + char spwn; //if stick man was spawned + unsigned int frames; //frames since last particle spawn - used when spawning LIGH +}; +typedef struct playerst playerst; + +struct wall_type +{ + pixel colour; + pixel eglow; // if emap set, add this to fire glow + int drawstyle; + const char *descs; +}; +typedef struct wall_type wall_type; + +struct gol_menu +{ + const char *name; + pixel colour; + int goltype; + const char *description; +}; +typedef struct gol_menu gol_menu; + +//#ifdef _cplusplus +class Simulation +{ +private: +public: + + Gravity * grav; + Air * air; + part_type ptypes[PT_NUM]; + part_transition ptransitions[PT_NUM]; + wall_type wtypes[UI_WALLCOUNT]; + gol_menu gmenu[NGOL]; + int goltype[NGOL]; + int grule[NGOL+1][10]; + playerst player; + playerst player2; + playerst fighters[256]; //255 is the maximum number of fighters + unsigned char fighcount; //Contains the number of fighters + int lighting_recreate; + int gravwl_timeout; + Particle portalp[CHANNELS][8][80]; + Particle emptyparticle; + int portal_rx[8]; + int portal_ry[8]; + int wireless[CHANNELS][2]; + char can_move[PT_NUM][PT_NUM]; + int parts_lastActiveIndex;// = NPART-1; + int pfree; + int NUM_PARTS; + int elementCount[PT_NUM]; + int ISWIRE; + sign * signs; + //Gol sim + int CGOL; + int ISGOL; + int GSPEED; + unsigned char gol[XRES][YRES]; + unsigned char gol2[XRES][YRES][NGOL+1]; + //Air sim + float (*vx)[XRES/CELL]; + float (*vy)[XRES/CELL]; + float (*pv)[XRES/CELL]; + float (*hv)[XRES/CELL]; + //Gravity sim + float *gravx;//gravx[(YRES/CELL) * (XRES/CELL)]; + float *gravy;//gravy[(YRES/CELL) * (XRES/CELL)]; + float *gravp;//gravp[(YRES/CELL) * (XRES/CELL)]; + float *gravmap;//gravmap[(YRES/CELL) * (XRES/CELL)]; + //Walls + unsigned char bmap[YRES/CELL][XRES/CELL]; + unsigned char emap[YRES/CELL][XRES/CELL]; + float fvx[YRES/CELL][XRES/CELL]; + float fvy[YRES/CELL][XRES/CELL]; + //Particles + Particle parts[NPART]; + int pmap[YRES][XRES]; + int photons[YRES][XRES]; + // + int gravityMode; + int airMode; + int ngrav_enable; + int legacy_enable; + int aheat_enable; + int VINE_MODE; + int water_equal_test; + int sys_pause; + int framerender; + int pretty_powder; + // + int sandcolour_r; + int sandcolour_g; + int sandcolour_b; //TODO: Make a single variable + //Stuff + int is_blocking(int t, int x, int y); + int is_boundary(int pt, int x, int y); + int find_next_boundary(int pt, int *x, int *y, int dm, int *em); + int pn_junction_sprk(int x, int y, int pt); + void photoelectric_effect(int nx, int ny); + unsigned direction_to_map(float dx, float dy, int t); + int do_move(int i, int x, int y, float nxf, float nyf); + int try_move(int i, int x, int y, int nx, int ny); + int eval_move(int pt, int nx, int ny, unsigned *rr); + void init_can_move(); + void create_cherenkov_photon(int pp); + void create_gain_photon(int pp); + void kill_part(int i); + int flood_prop(int x, int y, size_t propoffset, void * propvalue, int proptype); + int flood_prop_2(int x, int y, size_t propoffset, void * propvalue, int proptype, int parttype, char * bitmap); + int flood_water(int x, int y, int i, int originaly, int check); + void detach(int i); + void part_change_type(int i, int x, int y, int t); + int create_part_add_props(int p, int x, int y, int tv, int rx, int ry); + //int InCurrentBrush(int i, int j, int rx, int ry); + //int get_brush_flags(); + int create_part(int p, int x, int y, int t); + void delete_part(int x, int y, int flags); + int is_wire(int x, int y); + int is_wire_off(int x, int y); + void set_emap(int x, int y); + int parts_avg(int ci, int ni, int t); + void create_arc(int sx, int sy, int dx, int dy, int midpoints, int variance, int type, int flags); + int nearest_part(int ci, int t, int max_d); + void update_particles_i(int start, int inc); + void update_particles(); + void rotate_area(int area_x, int area_y, int area_w, int area_h, int invert); + void clear_area(int area_x, int area_y, int area_w, int area_h); + void create_box(int x1, int y1, int x2, int y2, int c, int flags); + int flood_parts(int x, int y, int c, int cm, int bm, int flags); + int create_parts(int x, int y, int rx, int ry, int c, int flags); + void create_line(int x1, int y1, int x2, int y2, int rx, int ry, int c, int flags); + void *transform_save(void *odata, int *size, matrix2d transform, vector2d translate); + void orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[]); + void orbitalparts_set(int *block1, int *block2, int resblock1[], int resblock2[]); + int get_wavelength_bin(int *wm); + int get_normal(int pt, int x, int y, float dx, float dy, float *nx, float *ny); + int get_normal_interp(int pt, float x0, float y0, float dx, float dy, float *nx, float *ny); + void clear_sim(); + void UpdateParticles(); + Simulation(); +}; +//#endif + +#endif /* SIMULATION_H_ */ diff --git a/src/Singleton.h b/src/Singleton.h new file mode 100644 index 0000000..6b2214e --- /dev/null +++ b/src/Singleton.h @@ -0,0 +1,16 @@ +#ifndef SINGLETON_H +#define SINGLETON_H + +template<typename T> + +class Singleton +{ +public: + static T& Ref() + { + static T instance; + return instance; + } +}; + +#endif // SINGLETON_H diff --git a/src/elements/O2.cpp b/src/elements/O2.cpp new file mode 100644 index 0000000..78b4229 --- /dev/null +++ b/src/elements/O2.cpp @@ -0,0 +1,30 @@ +#include "element.h" + +int update_O2(UPDATE_FUNC_ARGS) +{ + int r,rx,ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + + if ((r&0xFF)==PT_FIRE) + { + parts[r>>8].temp+=(rand()/(RAND_MAX/100)); + if(parts[r>>8].tmp&0x01) + parts[r>>8].temp=3473; + parts[r>>8].tmp |= 2; + } + if ((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM) + { + sim->create_part(i,x,y,PT_FIRE); + parts[i].temp+=(rand()/(RAND_MAX/100)); + parts[i].tmp |= 2; + } + + } + return 0; +} diff --git a/src/elements/acel.cpp b/src/elements/acel.cpp new file mode 100644 index 0000000..7ab9684 --- /dev/null +++ b/src/elements/acel.cpp @@ -0,0 +1,58 @@ +#include "element.h" + +int update_ACEL(UPDATE_FUNC_ARGS) { + int r, rx, ry; + parts[i].tmp = 0; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry) && !(rx && ry)) + { + r = pmap[y+ry][x+rx]; + if(!r) + r = sim->photons[y+ry][x+rx]; + if ((r>>8)>=NPART || !r) + continue; + if(sim->ptypes[r&0xFF].properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY)) + { + parts[r>>8].vx *= 1.1f; + parts[r>>8].vy *= 1.1f; + parts[i].tmp = 1; + } + } + return 0; +} + +int graphics_ACEL(GRAPHICS_FUNC_ARGS) +{ + if(cpart->tmp) + *pixel_mode |= PMODE_GLOW; + return 0; +} +int update_DCEL(UPDATE_FUNC_ARGS) { + int r, rx, ry; + parts[i].tmp = 0; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry) && !(rx && ry)) + { + r = pmap[y+ry][x+rx]; + if(!r) + r = sim->photons[y+ry][x+rx]; + if ((r>>8)>=NPART || !r) + continue; + if(sim->ptypes[r&0xFF].properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY)) + { + parts[r>>8].vx *= 0.9f; + parts[r>>8].vy *= 0.9f; + parts[i].tmp = 1; + } + } + return 0; +} + +int graphics_DCEL(GRAPHICS_FUNC_ARGS) +{ + if(cpart->tmp) + *pixel_mode |= PMODE_GLOW; + return 0; +} diff --git a/src/elements/acid.cpp b/src/elements/acid.cpp new file mode 100644 index 0000000..3a72b9d --- /dev/null +++ b/src/elements/acid.cpp @@ -0,0 +1,76 @@ +#include "element.h" + +int update_ACID(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, np; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_ACID && (r&0xFF)!=PT_CAUS) + { + if ((r&0xFF)==PT_PLEX || (r&0xFF)==PT_NITR || (r&0xFF)==PT_GUNP || (r&0xFF)==PT_RBDM || (r&0xFF)==PT_LRBD) + { + sim->part_change_type(i,x,y,PT_FIRE); + sim->part_change_type(r>>8,x+rx,y+ry,PT_FIRE); + parts[i].life = 4; + parts[r>>8].life = 4; + } + else if ((r&0xFF)==PT_WTRV) + { + if(!(rand()%250)) + { + sim->part_change_type(i, x, y, PT_CAUS); + parts[i].life = (rand()%50)+25; + sim->kill_part(r>>8); + } + } + else if (((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && sim->ptypes[r&0xFF].hardness>(rand()%1000))&&parts[i].life>=50) + { + if (sim->parts_avg(i, r>>8,PT_GLAS)!= PT_GLAS)//GLAS protects stuff from acid + { + float newtemp = ((60.0f-(float)sim->ptypes[r&0xFF].hardness))*7.0f; + if(newtemp < 0){ + newtemp = 0; + } + parts[i].temp += newtemp; + parts[i].life--; + sim->kill_part(r>>8); + } + } + else if (parts[i].life<=50) + { + sim->kill_part(i); + return 1; + } + } + } + for ( trade = 0; trade<2; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((r>>8)>=NPART || !r) + continue; + if ((r&0xFF)==PT_ACID&&(parts[i].life>parts[r>>8].life)&&parts[i].life>0)//diffusion + { + int temp = parts[i].life - parts[r>>8].life; + if (temp ==1) + { + parts[r>>8].life ++; + parts[i].life --; + } + else if (temp>0) + { + parts[r>>8].life += temp/2; + parts[i].life -= temp/2; + } + } + } + } + return 0; +} diff --git a/src/elements/amtr.cpp b/src/elements/amtr.cpp new file mode 100644 index 0000000..d119cc9 --- /dev/null +++ b/src/elements/amtr.cpp @@ -0,0 +1,28 @@ +#include "element.h" + +int update_AMTR(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_AMTR && (r&0xFF)!=PT_DMND && (r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && (r&0xFF)!=PT_NONE && (r&0xFF)!=PT_PHOT && (r&0xFF)!=PT_VOID && (r&0xFF)!=PT_BHOL && (r&0xFF)!=PT_NBHL && (r&0xFF)!=PT_PRTI && (r&0xFF)!=PT_PRTO) + { + parts[i].life++; + if (parts[i].life==4) + { + sim->kill_part(i); + return 1; + } + if (10>(rand()/(RAND_MAX/100))) + sim->create_part(r>>8, x+rx, y+ry, PT_PHOT); + else + sim->kill_part(r>>8); + sim->pv[y/CELL][x/CELL] -= 2.0f; + } + } + return 0; +} diff --git a/src/elements/anar.cpp b/src/elements/anar.cpp new file mode 100644 index 0000000..83eaf5a --- /dev/null +++ b/src/elements/anar.cpp @@ -0,0 +1,27 @@ +#include "element.h" + +int update_ANAR(UPDATE_FUNC_ARGS) { + int r, rx, ry; + + //if (parts[i].temp >= 0.23) + // parts[i].temp --; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_HFLM) + { + if (1>rand()%22) + { + sim->part_change_type(i,x,y,PT_HFLM); + parts[i].life = rand()%150+50; + parts[r>>8].temp = parts[i].temp = 0; + sim->pv[y/CELL][x/CELL] -= 0.5; + } + } + } + return 0; +} diff --git a/src/elements/aray.cpp b/src/elements/aray.cpp new file mode 100644 index 0000000..65b0d53 --- /dev/null +++ b/src/elements/aray.cpp @@ -0,0 +1,104 @@ +#include "element.h" + +int update_ARAY(UPDATE_FUNC_ARGS) { + int r, nxx, nyy, docontinue, nxi, nyi, rx, ry, nr, ry1, rx1; + if (parts[i].life==0) { + int colored =0; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK) { + int destroy = (parts[r>>8].ctype==PT_PSCN)?1:0; + int nostop = (parts[r>>8].ctype==PT_INST)?1:0; + for (docontinue = 1, nxx = 0, nyy = 0, nxi = rx*-1, nyi = ry*-1; docontinue; nyy+=nyi, nxx+=nxi) { + if (!(x+nxi+nxx<XRES && y+nyi+nyy<YRES && x+nxi+nxx >= 0 && y+nyi+nyy >= 0)) { + break; + } + r = pmap[y+nyi+nyy][x+nxi+nxx]; + if (!r) { + int nr = sim->create_part(-1, x+nxi+nxx, y+nyi+nyy, PT_BRAY); + if (nr!=-1) { + if (destroy) {//if it came from PSCN + parts[nr].tmp = 2; + parts[nr].life = 2; + } else + parts[nr].ctype = colored; + parts[nr].temp = parts[i].temp; + } + } else if (!destroy) { + if ((r&0xFF)==PT_BRAY&&parts[r>>8].tmp==0) {//if it hits another BRAY that isn't red + if (nyy!=0 || nxx!=0) { + parts[r>>8].life = 1020;//makes it last a while + parts[r>>8].tmp = 1; + if (!parts[r>>8].ctype)//and colors it if it isn't already + parts[r>>8].ctype = colored; + } + docontinue = 0;//then stop it + } else if ((r&0xFF)==PT_BRAY&&parts[r>>8].tmp==1) {//if it hits one that already was a long life, reset it + parts[r>>8].life = 1020; + //docontinue = 1; + } else if ((r&0xFF)==PT_FILT) {//get color if passed through FILT + colored = parts[r>>8].ctype; + //this if prevents BRAY from stopping on certain materials + } else if ((r&0xFF)!=PT_STOR && (r&0xFF)!=PT_INWR && (r&0xFF)!=PT_ARAY && (r&0xFF)!=PT_WIFI && !((r&0xFF)==PT_SWCH && parts[r>>8].life>=10)) { + if (nyy!=0 || nxx!=0) { + sim->create_part(-1, x+nxi+nxx, y+nyi+nyy, PT_SPRK); + } + //if (!(nostop && (ptypes[r&0xFF].properties&PROP_CONDUCTS))) { + if (!(nostop && parts[r>>8].ctype >= 0 && parts[r>>8].ctype < PT_NUM && (sim->ptypes[parts[r>>8].ctype].properties&PROP_CONDUCTS))) { + docontinue = 0; + } else { + docontinue = 1; + } + } else if((r&0xFF)==PT_STOR) { + if(parts[r>>8].tmp) + { + //Cause STOR to release + for(ry1 = 1; ry1 >= -1; ry1--){ + for(rx1 = 0; rx1 >= -1 && rx1 <= 1; rx1 = -rx1-rx1+1){ + int np = sim->create_part(-1, x+nxi+nxx+rx1, y+nyi+nyy+ry1, parts[r>>8].tmp); + if (np!=-1) + { + parts[np].temp = parts[r>>8].temp; + parts[np].life = parts[r>>8].flags; + parts[np].tmp = parts[r>>8].pavg[0]; + parts[np].ctype = parts[r>>8].pavg[1]; + parts[r>>8].tmp = 0; + parts[r>>8].life = 10; + break; + } + } + } + } + else + { + parts[r>>8].life = 10; + } + } + } else if (destroy) { + if ((r&0xFF)==PT_BRAY) { + parts[r>>8].life = 1; + docontinue = 1; + //this if prevents red BRAY from stopping on certain materials + } else if ((r&0xFF)==PT_STOR || (r&0xFF)==PT_INWR || (r&0xFF)==PT_ARAY || (r&0xFF)==PT_WIFI || (r&0xFF)==PT_FILT || ((r&0xFF)==PT_SWCH && parts[r>>8].life>=10)) { + if((r&0xFF)==PT_STOR) + { + parts[r>>8].tmp = 0; + parts[r>>8].life = 0; + } + docontinue = 1; + } else { + docontinue = 0; + } + } + } + } + //parts[i].life = 4; + } + } + return 0; +} diff --git a/src/elements/bang.cpp b/src/elements/bang.cpp new file mode 100644 index 0000000..658a567 --- /dev/null +++ b/src/elements/bang.cpp @@ -0,0 +1,75 @@ +#include "element.h" + +int update_BANG(UPDATE_FUNC_ARGS) { + int r, rx, ry, nb; + if(parts[i].tmp==0) + { + if(parts[i].temp>=673.0f) + parts[i].tmp = 1; + else + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM) + { + parts[i].tmp = 1; + } + else if ((r&0xFF)==PT_SPRK || (r&0xFF)==PT_LIGH) + { + parts[i].tmp = 1; + } + } + + } + else if(parts[i].tmp==1) + { + int tempvalue = 2; + sim->flood_prop(x, y, offsetof(Particle, tmp), &tempvalue, 0); + } + else if(parts[i].tmp==2) + { + parts[i].tmp = 3; + } + else if(parts[i].tmp>=3) + { + float otemp = parts[i].temp-275.13f; + //Explode!! + sim->pv[y/CELL][x/CELL] += 0.5f; + parts[i].tmp = 0; + if(!(rand()%3)) + { + if(!(rand()%2)) + { + sim->create_part(i, x, y, PT_FIRE); + parts[i].temp = restrict_flt((MAX_TEMP/4)+otemp, MIN_TEMP, MAX_TEMP); + } + else + { + sim->create_part(i, x, y, PT_SMKE); + parts[i].temp = restrict_flt((MAX_TEMP/4)+otemp, MIN_TEMP, MAX_TEMP); + } + } + else + { + if(!(rand()%15)) + { + sim->create_part(i, x, y, PT_BOMB); + parts[i].tmp = 1; + parts[i].life = 50; + parts[i].temp = restrict_flt((MAX_TEMP/3)+otemp, MIN_TEMP, MAX_TEMP); + parts[i].vx = rand()%20-10; + parts[i].vy = rand()%20-10; + } + else + { + sim->kill_part(i); + } + } + return 1; + } + return 0; +} diff --git a/src/elements/bcln.cpp b/src/elements/bcln.cpp new file mode 100644 index 0000000..8c00f95 --- /dev/null +++ b/src/elements/bcln.cpp @@ -0,0 +1,40 @@ +#include "element.h" + +int update_BCLN(UPDATE_FUNC_ARGS) { + if (!parts[i].life && sim->pv[y/CELL][x/CELL]>4.0f) + parts[i].life = rand()%40+80; + if (parts[i].life) + { + float advection = 0.1f; + parts[i].vx += advection*sim->vx[y/CELL][x/CELL]; + parts[i].vy += advection*sim->vy[y/CELL][x/CELL]; + } + if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || (parts[i].ctype==PT_LIFE && (parts[i].tmp<0 || parts[i].tmp>=NGOLALT))) + { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_BCLN && (r&0xFF)!=PT_STKM && + (r&0xFF)!=PT_STKM2 && (r&0xFF)!=PT_PBCN && + (r&0xFF)<PT_NUM) + { + parts[i].ctype = r&0xFF; + if ((r&0xFF)==PT_LIFE) + parts[i].tmp = parts[r>>8].ctype; + } + } + } + else { + if (parts[i].ctype==PT_LIFE) sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype|(parts[i].tmp<<8)); + else sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype); + } + return 0; +} diff --git a/src/elements/bcol.cpp b/src/elements/bcol.cpp new file mode 100644 index 0000000..d941508 --- /dev/null +++ b/src/elements/bcol.cpp @@ -0,0 +1,68 @@ +#include "element.h" + +int update_BCOL(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, temp; + if (parts[i].life<=0) { + sim->create_part(i, x, y, PT_FIRE); + return 1; + } else if (parts[i].life < 100) { + parts[i].life--; + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, PT_FIRE); + } + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM) && 1>(rand()%500)) + { + if (parts[i].life>100) { + parts[i].life = 99; + } + } + if ((r&0xFF)==PT_LAVA && 1>(rand()%500)) + { + if (parts[r>>8].ctype == PT_IRON) { + parts[r>>8].ctype = PT_METL; + sim->kill_part(i); + return 1; + } + } + } + /*if(100-parts[i].life > parts[i].tmp2) + parts[i].tmp2 = 100-parts[i].life; + if(parts[i].tmp2 < 0) parts[i].tmp2 = 0; + for ( trade = 0; trade<4; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_COAL || (r&0xFF)==PT_BCOL)&&(parts[i].tmp2>parts[r>>8].tmp2)&&parts[i].tmp2>0)//diffusion + { + int temp = parts[i].tmp2 - parts[r>>8].tmp2; + if(temp < 10) + continue; + if (temp ==1) + { + parts[r>>8].tmp2 ++; + parts[i].tmp2 --; + } + else if (temp>0) + { + parts[r>>8].tmp2 += temp/2; + parts[i].tmp2 -= temp/2; + } + } + } + }*/ + if(parts[i].temp > parts[i].tmp2) + parts[i].tmp2 = parts[i].temp; + return 0; +} diff --git a/src/elements/bizr.cpp b/src/elements/bizr.cpp new file mode 100644 index 0000000..538b87f --- /dev/null +++ b/src/elements/bizr.cpp @@ -0,0 +1,44 @@ +#include "element.h" + +//Used by ALL 3 BIZR states +int update_BIZR(UPDATE_FUNC_ARGS) { + int r, rx, ry, nr, ng, nb, na; + float tr, tg, tb, ta, mr, mg, mb, ma; + float blend; + if(parts[i].dcolour){ + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_BIZR && (r&0xFF)!=PT_BIZRG && (r&0xFF)!=PT_BIZRS) + { + blend = 0.95f; + tr = (parts[r>>8].dcolour>>16)&0xFF; + tg = (parts[r>>8].dcolour>>8)&0xFF; + tb = (parts[r>>8].dcolour)&0xFF; + ta = (parts[r>>8].dcolour>>24)&0xFF; + + mr = (parts[i].dcolour>>16)&0xFF; + mg = (parts[i].dcolour>>8)&0xFF; + mb = (parts[i].dcolour)&0xFF; + ma = (parts[i].dcolour>>24)&0xFF; + + nr = (tr*blend) + (mr*(1-blend)); + ng = (tg*blend) + (mg*(1-blend)); + nb = (tb*blend) + (mb*(1-blend)); + na = (ta*blend) + (ma*(1-blend)); + + parts[r>>8].dcolour = nr<<16 | ng<<8 | nb | na<<24; + } + } + } + if(((r = sim->photons[y][x])&0xFF)==PT_PHOT || ((r = pmap[y][x])&0xFF)==PT_PHOT) + { + sim->part_change_type(r>>8, x, y, PT_ELEC); + parts[r>>8].ctype = 0; + } + return 0; +} diff --git a/src/elements/bmtl.cpp b/src/elements/bmtl.cpp new file mode 100644 index 0000000..a3dc4b8 --- /dev/null +++ b/src/elements/bmtl.cpp @@ -0,0 +1,29 @@ +#include "element.h" + +int update_BMTL(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, tempFactor; + if (parts[i].tmp>1) + { + parts[i].tmp--; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + rt = parts[r>>8].type; + if ((rt==PT_METL || rt==PT_IRON) && 1>(rand()/(RAND_MAX/100))) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_BMTL); + parts[r>>8].tmp=(parts[i].tmp<=7)?parts[i].tmp=1:parts[i].tmp-(rand()%5);//rand()/(RAND_MAX/300)+100; + } + } + } + else if (parts[i].tmp==1 && 1>rand()%1000) + { + parts[i].tmp = 0; + sim->part_change_type(i,x,y,PT_BRMT); + } + return 0; +} diff --git a/src/elements/bomb.cpp b/src/elements/bomb.cpp new file mode 100644 index 0000000..b2e9e7d --- /dev/null +++ b/src/elements/bomb.cpp @@ -0,0 +1,85 @@ +#include "element.h" + +int update_BOMB(UPDATE_FUNC_ARGS) { + int r, rx, ry, nb; + //Spark is used so much now that it should be a seperate element. + if (parts[i].tmp==1) { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->ptypes[r&0xFF].properties & (TYPE_SOLID | TYPE_PART | TYPE_LIQUID) && !(sim->ptypes[r&0xFF].properties & PROP_SPARKSETTLE)) { + sim->kill_part(i); + return 1; + } + } + } else if (parts[i].tmp==0) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_BOMB && (r&0xFF)!=PT_DMND && (r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && (r&0xFF)!=PT_BCLN) { + int rad = 8; + int nxi; + int nxj; + pmap[y][x] = 0; + for (nxj=-(rad+1); nxj<=(rad+1); nxj++) + for (nxi=-(rad+1); nxi<=(rad+1); nxi++) + if ((pow(nxi,2))/(pow((rad+1),2))+(pow(nxj,2))/(pow((rad+1),2))<=1) { + nb = sim->create_part(-1, x+nxi, y+nxj, PT_BOMB); + if (nb!=-1) { + parts[nb].tmp = 1; + parts[nb].life = 50; + parts[nb].temp = MAX_TEMP; + parts[nb].vx = rand()%20-10; + parts[nb].vy = rand()%20-10; + } + } + for (nxj=-rad; nxj<=rad; nxj++) + for (nxi=-rad; nxi<=rad; nxi++) + if ((pow(nxi,2))/(pow(rad,2))+(pow(nxj,2))/(pow(rad,2))<=1) + if ((pmap[y+nxj][x+nxi]&0xFF)!=PT_DMND && (pmap[y+nxj][x+nxi]&0xFF)!=PT_CLNE && (pmap[y+nxj][x+nxi]&0xFF)!=PT_PCLN && (pmap[y+nxj][x+nxi]&0xFF)!=PT_BCLN) { + sim->delete_part(x+nxi, y+nxj, 0);//it SHOULD kill anything but the exceptions above, doesn't seem to always work + sim->pv[(y+nxj)/CELL][(x+nxi)/CELL] += 0.1f; + nb = sim->create_part(-1, x+nxi, y+nxj, PT_BOMB); + if (nb!=-1) { + parts[nb].tmp = 2; + parts[nb].life = 2; + parts[nb].temp = MAX_TEMP; + } + } + //create_parts(x, y, 9, 9, PT_BOMB); + //create_parts(x, y, 8, 8, PT_NONE); + sim->kill_part(i); + return 1; + } + } + } + return 0; +} +int graphics_BOMB(GRAPHICS_FUNC_ARGS) +{ + if (cpart->tmp==0) { + //Normal bomb + *pixel_mode |= PMODE_FLARE; + } + else if(cpart->tmp==2) + { + //Flash + *pixel_mode = PMODE_FLAT | FIRE_ADD; + *colr = *colg = *colb = *firer = *fireg = *fireb = *firea = 255; + } + else + { + //Flying spark + *pixel_mode = PMODE_SPARK | PMODE_ADD; + *cola = 4*cpart->life; + } + return 0; +} diff --git a/src/elements/boyl.cpp b/src/elements/boyl.cpp new file mode 100644 index 0000000..e4ee6d2 --- /dev/null +++ b/src/elements/boyl.cpp @@ -0,0 +1,43 @@ +#include "element.h" + +int update_BOYL(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (sim->pv[y/CELL][x/CELL]<(parts[i].temp/100)) + sim->pv[y/CELL][x/CELL] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL][x/CELL]); + if (y+CELL<YRES && sim->pv[y/CELL+1][x/CELL]<(parts[i].temp/100)) + sim->pv[y/CELL+1][x/CELL] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL+1][x/CELL]); + if (x+CELL<XRES) + { + sim->pv[y/CELL][x/CELL+1] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL][x/CELL+1]); + if (y+CELL<YRES) + sim->pv[y/CELL+1][x/CELL+1] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL+1][x/CELL+1]); + } + if (y-CELL>=0 && sim->pv[y/CELL-1][x/CELL]<(parts[i].temp/100)) + sim->pv[y/CELL-1][x/CELL] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL-1][x/CELL]); + if (x-CELL>=0) + { + sim->pv[y/CELL][x/CELL-1] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL][x/CELL-1]); + if (y-CELL>=0) + sim->pv[y/CELL-1][x/CELL-1] += 0.001f*((parts[i].temp/100)-sim->pv[y/CELL-1][x/CELL-1]); + } + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && + x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR && 1>rand()%30) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_FOG); + } + else if ((r&0xFF)==PT_O2 && 1>rand()%9) + { + sim->kill_part(r>>8); + sim->part_change_type(i,x,y,PT_WATR); + sim->pv[y/CELL][x/CELL] += 4.0; + } + } + return 0; +} diff --git a/src/elements/brmt.cpp b/src/elements/brmt.cpp new file mode 100644 index 0000000..c23bd99 --- /dev/null +++ b/src/elements/brmt.cpp @@ -0,0 +1,35 @@ +#include "element.h" + +int update_BRMT(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, tempFactor; + if (parts[i].temp > (250.0f+273.15f)) + { + printf("%f\n", (250.0f+273.15f)-parts[i].temp); + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + rt = parts[r>>8].type; + tempFactor = 1000 - (((250.0f+273.15f)-parts[i].temp)*2); + if(tempFactor < 2) + tempFactor = 2; + if ((rt==PT_BREC) && 1 > (rand()%tempFactor)) + { + if(rand()%2) + { + sim->create_part(r>>8, x+rx, y+ry, PT_THRM); + } + else + { sim->create_part(i, x, y, PT_THRM); + } + return 1; + //part_change_type(r>>8,x+rx,y+ry,PT_BMTL); + //parts[r>>8].tmp=(parts[i].tmp<=7)?parts[i].tmp=1:parts[i].tmp-(rand()%5);//rand()/(RAND_MAX/300)+100; + } + } + } + return 0; +} diff --git a/src/elements/btry.cpp b/src/elements/btry.cpp new file mode 100644 index 0000000..3f11003 --- /dev/null +++ b/src/elements/btry.cpp @@ -0,0 +1,24 @@ +#include "element.h" + +int update_BTRY(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + rt = parts[r>>8].type; + if (sim->parts_avg(i,r>>8,PT_INSL) != PT_INSL) + { + if ((sim->ptypes[rt].properties&PROP_CONDUCTS) && !(rt==PT_WATR||rt==PT_SLTW||rt==PT_NTCT||rt==PT_PTCT||rt==PT_INWR) && parts[r>>8].life==0 && abs(rx)+abs(ry) < 4) + { + parts[r>>8].life = 4; + parts[r>>8].ctype = rt; + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + } + } + } + return 0; +} diff --git a/src/elements/c5.cpp b/src/elements/c5.cpp new file mode 100644 index 0000000..412245f --- /dev/null +++ b/src/elements/c5.cpp @@ -0,0 +1,24 @@ +#include "element.h" + +int update_C5(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)!=PT_C5 && parts[r>>8].temp<100)||(r&0xFF)==PT_HFLM) + { + if (1>rand()%6) + { + sim->part_change_type(i,x,y,PT_HFLM); + parts[r>>8].temp = parts[i].temp = 0; + parts[i].life = rand()%150+50; + sim->pv[y/CELL][x/CELL] += 1.5; + } + } + } + return 0; +} diff --git a/src/elements/caus.cpp b/src/elements/caus.cpp new file mode 100644 index 0000000..2ec268e --- /dev/null +++ b/src/elements/caus.cpp @@ -0,0 +1,35 @@ +#include "element.h" + +int update_CAUS(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, np; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_ACID && (r&0xFF)!=PT_CAUS) + { + if (((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && sim->ptypes[r&0xFF].hardness>(rand()%1000))&&parts[i].life>=50) + { + if (sim->parts_avg(i, r>>8,PT_GLAS)!= PT_GLAS)//GLAS protects stuff from acid + { + float newtemp = ((60.0f-(float)sim->ptypes[r&0xFF].hardness))*7.0f; + if(newtemp < 0){ + newtemp = 0; + } + parts[i].temp += newtemp; + parts[i].life--; + sim->kill_part(r>>8); + } + } + else if (parts[i].life<=50) + { + sim->kill_part(i); + return 1; + } + } + } + return 0; +} diff --git a/src/elements/cbnw.cpp b/src/elements/cbnw.cpp new file mode 100644 index 0000000..cf0c13e --- /dev/null +++ b/src/elements/cbnw.cpp @@ -0,0 +1,89 @@ +#include "element.h" + +int update_CBNW(UPDATE_FUNC_ARGS) { + int r, rx, ry, oldt; + oldt = parts[i].tmp; + if (sim->pv[y/CELL][x/CELL]<=3) + { + if(20>(rand()%80000)) + { + sim->part_change_type(i,x,y,PT_CO2); + parts[i].ctype = 5; + sim->pv[y/CELL][x/CELL] += 0.5f; + } + else if(sim->pv[y/CELL][x/CELL]<=-0.5) + { + sim->part_change_type(i,x,y,PT_CO2); + parts[i].ctype = 5; + sim->pv[y/CELL][x/CELL] += 0.5f; + } + } + if (parts[i].tmp>0) + parts[i].tmp--; + if(!(rand()%200)) + { + parts[i].tmp2 = rand()%40; + } else if(parts[i].tmp2!=20) { + parts[i].tmp2 -= (parts[i].tmp2>20)?1:-1; + } + if(oldt==1) + { + //Explode + if(rand()%4) + { + sim->part_change_type(i,x,y,PT_CO2); + parts[i].ctype = 5; + sim->pv[y/CELL][x/CELL] += 0.2f; + } + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((sim->ptypes[r&0xFF].properties&TYPE_PART) && parts[i].tmp == 0 && 1>(rand()%250)) + { + //Start explode + parts[i].tmp = rand()%25;//(rand()%100)+50; + } + else if((sim->ptypes[r&0xFF].properties&TYPE_SOLID) && (r&0xFF)!=PT_DMND && (r&0xFF)!=PT_GLAS && parts[i].tmp == 0 && (2-sim->pv[y/CELL][x/CELL])>(rand()%20000)) + { + if(rand()%2) + { + sim->part_change_type(i,x,y,PT_CO2); + parts[i].ctype = 5; + sim->pv[y/CELL][x/CELL] += 0.2f; + } + } + if ((r&0xFF)==PT_CBNW) + { + if(!parts[i].tmp && parts[r>>8].tmp) + { + parts[i].tmp = parts[r>>8].tmp; + if((r>>8)>i) //If the other particle hasn't been life updated + parts[i].tmp--; + } + else if(parts[i].tmp && !parts[r>>8].tmp) + { + parts[r>>8].tmp = parts[i].tmp; + if((r>>8)>i) //If the other particle hasn't been life updated + parts[r>>8].tmp++; + } + } + if (((r&0xFF)==PT_RBDM||(r&0xFF)==PT_LRBD) && (sim->legacy_enable||parts[i].temp>(273.15f+12.0f)) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + if ((r&0xFF)==PT_FIRE){ + sim->kill_part(r>>8); + if(1>(rand()%150)){ + sim->kill_part(i); + return 1; + } + } + } + return 0; +} diff --git a/src/elements/clne.cpp b/src/elements/clne.cpp new file mode 100644 index 0000000..13b25b9 --- /dev/null +++ b/src/elements/clne.cpp @@ -0,0 +1,32 @@ +#include "element.h" + +int update_CLNE(UPDATE_FUNC_ARGS) { + if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || (parts[i].ctype==PT_LIFE && (parts[i].tmp<0 || parts[i].tmp>=NGOLALT))) + { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_BCLN && (r&0xFF)!=PT_STKM && + (r&0xFF)!=PT_PBCN && (r&0xFF)!=PT_STKM2 && + (r&0xFF)<PT_NUM) + { + parts[i].ctype = r&0xFF; + if ((r&0xFF)==PT_LIFE) + parts[i].tmp = parts[r>>8].ctype; + } + } + } + else { + if (parts[i].ctype==PT_LIFE) sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype|(parts[i].tmp<<8)); + else sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype); + } + return 0; +} diff --git a/src/elements/clst.cpp b/src/elements/clst.cpp new file mode 100644 index 0000000..2c31d87 --- /dev/null +++ b/src/elements/clst.cpp @@ -0,0 +1,38 @@ +#include "element.h" + +int update_CLST(UPDATE_FUNC_ARGS) { + int r, rx, ry; + float cxy; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR && 1>(rand()%1500)) + { + sim->part_change_type(i,x,y,PT_PSTS); + sim->kill_part(r>>8); + } + if ((r&0xFF)==PT_NITR) + { + sim->create_part(i, x, y, PT_BANG); + sim->create_part(r>>8, x+rx, y+ry, PT_BANG); + } + if ((r&0xFF)==PT_CLST) + { + if(parts[i].temp <195) + cxy = 0.05; + if(parts[i].temp >= 195 && parts[i].temp <295) + cxy = 0.015; + if(parts[i].temp >= 295 && parts[i].temp <350) + cxy = 0.01; + if(parts[i].temp > 350) + cxy = 0.005; + parts[i].vx += cxy*rx; + parts[i].vy += cxy*ry;//These two can be set not to calculate over 350 later. They do virtually nothing over 0.005. + } + } + return 0; +} diff --git a/src/elements/co2.cpp b/src/elements/co2.cpp new file mode 100644 index 0000000..5a3bbf5 --- /dev/null +++ b/src/elements/co2.cpp @@ -0,0 +1,31 @@ +#include "element.h" + +int update_CO2(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (20>(rand()%40000)&&parts[i].ctype==5) + { + parts[i].ctype = 0; + sim->create_part(-3, x, y, PT_WATR); + } + if ((r>>8)>=NPART || !r) + continue; + if ((r&0xFF)==PT_FIRE){ + sim->kill_part(r>>8); + if(1>(rand()%150)){ + sim->kill_part(i); + return 1; + } + } + if (((r&0xFF)==PT_WATR || (r&0xFF)==PT_DSTW) && 1>(rand()%250)) + { + sim->part_change_type(i,x,y,PT_CBNW); + sim->kill_part(r>>8); + } + } + return 0; +} diff --git a/src/elements/coal.cpp b/src/elements/coal.cpp new file mode 100644 index 0000000..256aa69 --- /dev/null +++ b/src/elements/coal.cpp @@ -0,0 +1,75 @@ +#include "element.h" + +int update_COAL(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, temp; + if (parts[i].life<=0) { + sim->create_part(i, x, y, PT_FIRE); + return 1; + } else if (parts[i].life < 100) { + parts[i].life--; + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, PT_FIRE); + } + if ((sim->pv[y/CELL][x/CELL] > 4.3f)&&parts[i].tmp>40) + parts[i].tmp=39; + else if (parts[i].tmp<40&&parts[i].tmp>0) + parts[i].tmp--; + else if (parts[i].tmp<=0) { + sim->create_part(i, x, y, PT_BCOL); + return 1; + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM) && 1>(rand()%500)) + { + if (parts[i].life>100) { + parts[i].life = 99; + } + } + if ((r&0xFF)==PT_LAVA && 1>(rand()%500)) + { + if (parts[r>>8].ctype == PT_IRON) { + parts[r>>8].ctype = PT_METL; + sim->kill_part(i); + return 1; + } + } + } + /*if(100-parts[i].life > parts[i].tmp2) + parts[i].tmp2 = 100-parts[i].life; + if(parts[i].tmp2 < 0) parts[i].tmp2 = 0; + for ( trade = 0; trade<4; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_COAL || (r&0xFF)==PT_BCOL)&&(parts[i].tmp2>parts[r>>8].tmp2)&&parts[i].tmp2>0)//diffusion + { + int temp = parts[i].tmp2 - parts[r>>8].tmp2; + if(temp < 10) + continue; + if (temp ==1) + { + parts[r>>8].tmp2 ++; + parts[i].tmp2 --; + } + else if (temp>0) + { + parts[r>>8].tmp2 += temp/2; + parts[i].tmp2 -= temp/2; + } + } + } + }*/ + if(parts[i].temp > parts[i].tmp2) + parts[i].tmp2 = parts[i].temp; + return 0; +} diff --git a/src/elements/conv.cpp b/src/elements/conv.cpp new file mode 100644 index 0000000..ce4ee48 --- /dev/null +++ b/src/elements/conv.cpp @@ -0,0 +1,45 @@ +#include "element.h" + +int update_CONV(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || (parts[i].ctype==PT_LIFE && (parts[i].tmp<0 || parts[i].tmp>=NGOLALT))) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_BCLN && (r&0xFF)!=PT_STKM && + (r&0xFF)!=PT_PBCN && (r&0xFF)!=PT_STKM2 && + (r&0xFF)!=PT_CONV && (r&0xFF)<PT_NUM) + { + parts[i].ctype = r&0xFF; + if ((r&0xFF)==PT_LIFE) + parts[i].tmp = parts[r>>8].ctype; + } + } + } + else if(parts[i].ctype>0 && parts[i].ctype<PT_NUM && parts[i].ctype!=PT_CONV) { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if((r&0xFF)!=PT_CONV && (r&0xFF)!=parts[i].ctype) + { + if (parts[i].ctype==PT_LIFE) sim->create_part(r>>8, x+rx, y+ry, parts[i].ctype|(parts[i].tmp<<8)); + else sim->create_part(r>>8, x+rx, y+ry, parts[i].ctype); + } + } + } + return 0; +} diff --git a/src/elements/dest.cpp b/src/elements/dest.cpp new file mode 100644 index 0000000..014fad4 --- /dev/null +++ b/src/elements/dest.cpp @@ -0,0 +1,66 @@ +#include "element.h" + +int update_DEST(UPDATE_FUNC_ARGS) { + int r,rx,ry,topv; + rx=rand()%5-2; + ry=rand()%5-2; + + r = pmap[y+ry][x+rx]; + if (!r || (r&0xFF)==PT_DEST || (r&0xFF)==PT_DMND) + return 0; + + if (parts[i].life<=0 || parts[i].life>37) + { + parts[i].life=30+rand()%20; + parts[i].temp+=20000; + sim->pv[y/CELL][x/CELL]+=60.0f; + } + parts[i].temp+=10000; + if ((r&0xFF)==PT_PLUT || (r&0xFF)==PT_DEUT) + { + sim->pv[y/CELL][x/CELL]+=20.0f; + parts[i].temp+=18000; + if (rand()%2==0) + { + float orig_temp = parts[r>>8].temp; + sim->create_part(r>>8, x+rx, y+ry, PT_NEUT); + parts[r>>8].temp = restrict_flt(orig_temp+40000.0f, MIN_TEMP, MAX_TEMP); + sim->pv[y/CELL][x/CELL] += 10.0f; + parts[i].life-=4; + } + } + else if ((r&0xFF)==PT_INSL) + { + sim->create_part(r>>8, x+rx, y+ry, PT_PLSM); + } + else if (rand()%3==0) + { + sim->kill_part(r>>8); + parts[i].life -= 4*((sim->ptypes[r&0xFF].properties&TYPE_SOLID)?3:1); + if (parts[i].life<=0) + parts[i].life=1; + parts[i].temp+=10000; + } + else + { + if (sim->ptypes[r&0xFF].hconduct) parts[r>>8].temp = restrict_flt(parts[r>>8].temp+10000.0f, MIN_TEMP, MAX_TEMP); + } + topv=sim->pv[y/CELL][x/CELL]/9+parts[r>>8].temp/900; + if (topv>40.0f) + topv=40.0f; + sim->pv[y/CELL][x/CELL]+=40.0f+topv; + parts[i].temp = restrict_flt(parts[i].temp, MIN_TEMP, MAX_TEMP); + return 0; +} +int graphics_DEST(GRAPHICS_FUNC_ARGS) +{ + if(cpart->life) + { + *pixel_mode |= PMODE_LFLARE; + } + else + { + *pixel_mode |= PMODE_SPARK; + } + return 0; +} diff --git a/src/elements/deut.cpp b/src/elements/deut.cpp new file mode 100644 index 0000000..03de364 --- /dev/null +++ b/src/elements/deut.cpp @@ -0,0 +1,89 @@ +#include "element.h" + +int update_DEUT(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, np; + int maxlife = ((10000/(parts[i].temp + 1))-1); + if ((10000%((int)parts[i].temp+1))>rand()%((int)parts[i].temp+1)) + maxlife ++; + if (parts[i].life < maxlife) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r || (parts[i].life >=maxlife)) + continue; + if ((r&0xFF)==PT_DEUT&&33>=rand()/(RAND_MAX/100)+1) + { + if ((parts[i].life + parts[r>>8].life + 1) <= maxlife) + { + parts[i].life += parts[r>>8].life + 1; + sim->kill_part(r>>8); + } + } + } + } + else + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (parts[i].life<=maxlife) + continue; + if ((!r)&&parts[i].life>=1)//if nothing then create deut + { + np = sim->create_part(-1,x+rx,y+ry,PT_DEUT); + if (np<0) continue; + parts[i].life--; + parts[np].temp = parts[i].temp; + parts[np].life = 0; + } + } + for ( trade = 0; trade<4; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_DEUT&&(parts[i].life>parts[r>>8].life)&&parts[i].life>0)//diffusion + { + int temp = parts[i].life - parts[r>>8].life; + if (temp ==1) + { + parts[r>>8].life ++; + parts[i].life --; + } + else if (temp>0) + { + parts[r>>8].life += temp/2; + parts[i].life -= temp/2; + } + } + } + } + return 0; +} + +int graphics_DEUT(GRAPHICS_FUNC_ARGS) +{ + if(cpart->life>=700) + { + *colr += cpart->life*1; + *colg += cpart->life*2; + *colb += cpart->life*3; + *pixel_mode |= PMODE_GLOW; + } + else + { + *colr += cpart->life*1; + *colg += cpart->life*2; + *colb += cpart->life*3; + *pixel_mode |= PMODE_BLUR; + } + return 0; +} diff --git a/src/elements/dlay.cpp b/src/elements/dlay.cpp new file mode 100644 index 0000000..4643b30 --- /dev/null +++ b/src/elements/dlay.cpp @@ -0,0 +1,48 @@ +#include "element.h" + +int update_DLAY(UPDATE_FUNC_ARGS) { + int r, rx, ry, oldl; + oldl = parts[i].life; + if (parts[i].life>0) + parts[i].life--; + //if (parts[i].life==1) + //{ + if (parts[i].temp>=256.0+273.15) + parts[i].temp=256.0+273.15; + if (parts[i].temp<= -256.0+273.15) + parts[i].temp = -256.0+273.15; + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK && parts[i].life==0 && parts[r>>8].ctype==PT_PSCN) + { + parts[i].life = (int)(parts[i].temp-273.15); + } + else if ((r&0xFF)==PT_DLAY) + { + if(!parts[i].life && parts[r>>8].life) + { + parts[i].life = parts[r>>8].life; + if((r>>8)>i) //If the other particle hasn't been life updated + parts[i].life--; + } + else if(parts[i].life && !parts[r>>8].life) + { + parts[r>>8].life = parts[i].life; + if((r>>8)>i) //If the other particle hasn't been life updated + parts[r>>8].life++; + } + } + else if((r&0xFF)==PT_NSCN && oldl==1) + { + sim->create_part(-1, x+rx, y+ry, PT_SPRK); + } + } + //} + return 0; +} diff --git a/src/elements/dstw.cpp b/src/elements/dstw.cpp new file mode 100644 index 0000000..03ae7dd --- /dev/null +++ b/src/elements/dstw.cpp @@ -0,0 +1,39 @@ +#include "element.h" + +int update_DSTW(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SALT && 1>(rand()%250)) + { + sim->part_change_type(i,x,y,PT_SLTW); + sim->part_change_type(r>>8,x+rx,y+ry,PT_SLTW); + } + if (((r&0xFF)==PT_WATR||(r&0xFF)==PT_SLTW) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_WATR); + } + if ((r&0xFF)==PT_SLTW && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_SLTW); + } + if (((r&0xFF)==PT_RBDM||(r&0xFF)==PT_LRBD) && (sim->legacy_enable||parts[i].temp>12.0f) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + if ((r&0xFF)==PT_FIRE){ + sim->kill_part(r>>8); + if(1>(rand()%150)){ + sim->kill_part(i); + return 1; + } + } + } + return 0; +} diff --git a/src/elements/elec.cpp b/src/elements/elec.cpp new file mode 100644 index 0000000..6b06f8f --- /dev/null +++ b/src/elements/elec.cpp @@ -0,0 +1,101 @@ +#include "element.h" + +int update_ELEC(UPDATE_FUNC_ARGS) { + int r, rt, rx, ry, nb, rrx, rry; + float rr, rrr; + parts[i].pavg[0] = x; + parts[i].pavg[1] = y; + if(pmap[y][x]==PT_GLOW) + { + sim->part_change_type(i, x, y, PT_PHOT); + } + for (rx=-2; rx<=2; rx++) + for (ry=-2; ry<=2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) { + r = pmap[y+ry][x+rx]; + if (!r) + r = sim->photons[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_GLAS) + { + //fire_r[y/CELL][x/CELL] += rand()%200; //D: Doesn't work with OpenGL, also shouldn't be here TODO: FIX THIS SHIT + //fire_g[y/CELL][x/CELL] += rand()%200; + //fire_b[y/CELL][x/CELL] += rand()%200; + for (rrx=-1; rrx<=1; rrx++) + { + for (rry=-1; rry<=1; rry++) + { + if (x+rx+rrx>=0 && y+ry+rry>=0 && x+rx+rrx<XRES && y+ry+rry<YRES) { + nb = sim->create_part(-1, x+rx+rrx, y+ry+rry, PT_BOMB); + if (nb!=-1) { + parts[nb].tmp = 1; + parts[nb].life = 50; + parts[nb].temp = 400.0f; + parts[nb].vx = rand()%20-10; + parts[nb].vy = rand()%20-10; + } + } + } + } + sim->kill_part(i); + return 1; + } + if ((r&0xFF)==PT_LCRY) + { + parts[r>>8].tmp2 = 5+rand()%5; + } + if ((r&0xFF)==PT_WATR || (r&0xFF)==PT_DSTW || (r&0xFF)==PT_SLTW || (r&0xFF)==PT_CBNW) + { + if(rand()%2) + { + sim->create_part(r>>8, x+rx, y+ry, PT_H2); + sim->part_change_type(i, x, y, PT_O2); + parts[i].life = 0; + parts[i].ctype = 0; + return 1; + } + else + { + sim->create_part(r>>8, x+rx, y+ry, PT_O2); + sim->part_change_type(i, x, y, PT_H2); + parts[i].life = 0; + parts[i].ctype = 0; + return 1; + } + } + if ((r&0xFF)==PT_NEUT) + { + sim->part_change_type(r>>8, x+rx, y+ry, PT_H2); + parts[r>>8].life = 0; + parts[r>>8].ctype = 0; + } + if ((r&0xFF)==PT_DEUT) + { + if(parts[r>>8].life < 6000) + parts[r>>8].life += 1; + parts[r>>8].temp = 0; + parts[i].temp = 0; + sim->kill_part(i); + return 1; + } + if (sim->ptypes[r&0xFF].properties & PROP_CONDUCTS) + { + sim->create_part(-1, x+rx, y+ry, PT_SPRK); + sim->kill_part(i); + return 1; + } + } + return 0; +} + +int graphics_ELEC(GRAPHICS_FUNC_ARGS) +{ + *firea = 70; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode |= FIRE_ADD; + return 0; +} diff --git a/src/elements/elementmisc.cpp b/src/elements/elementmisc.cpp new file mode 100644 index 0000000..a169e80 --- /dev/null +++ b/src/elements/elementmisc.cpp @@ -0,0 +1,12 @@ +#include "element.h" + +int update_MISC(UPDATE_FUNC_ARGS) { + /*int t = parts[i].type; + if (t==PT_LOVE) + ISLOVE=1; + else if (t==PT_LOLZ) + ISLOLZ=1; + else if (t==PT_GRAV) + ISGRAV=1;*/ + return 0; +} diff --git a/src/elements/emp.cpp b/src/elements/emp.cpp new file mode 100644 index 0000000..a187196 --- /dev/null +++ b/src/elements/emp.cpp @@ -0,0 +1,128 @@ +#include "element.h" + +int update_EMP(UPDATE_FUNC_ARGS) { + int r,rx,ry,ok=0,t,n,nx,ny; + if (parts[i].life) + return 0; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK) + { + ok=1; + break; + } + } + if (!ok) + return 0; + parts[i].life=220; + //emp_decor+=3; TODO: Fix + //if (emp_decor>40) + // emp_decor=40; + for (r=0; r<=sim->parts_lastActiveIndex; r++) + { + t=parts[r].type; + rx=parts[r].x; + ry=parts[r].y; + if (t==PT_SPRK || (t==PT_SWCH && parts[r].life!=0 && parts[r].life!=10) || (t==PT_WIRE && parts[r].ctype>0)) + { + int is_elec=0; + if ((parts[r].ctype==PT_PSCN || parts[r].ctype==PT_NSCN || parts[r].ctype==PT_PTCT || + parts[r].ctype==PT_NTCT || parts[r].ctype==PT_INST || parts[r].ctype==PT_SWCH) || t==PT_WIRE || t==PT_SWCH) + { + is_elec=1; + if (sim->ptypes[parts[r].type].hconduct && rand()%100==0) + parts[r].temp = restrict_flt(parts[r].temp+3000.0f, MIN_TEMP, MAX_TEMP); + if (rand()%80==0) + sim->part_change_type(r, rx, ry, PT_BREC); + else if (rand()%120==0) + sim->part_change_type(r, rx, ry, PT_NTCT); + } + + for (nx=-2; nx<3; nx++) + for (ny=-2; ny<3; ny++) + if (rx+nx>=0 && ry+ny>=0 && rx+nx<XRES && ry+ny<YRES && (rx || ry)) + { + n = pmap[ry+ny][rx+nx]; + if (!n) + continue; + /*if ((n&0xFF)==PT_BTRY && rand()%60==0) + { + part_change_type(n>>8, rx+nx, ry+ny, PT_PLSM); + parts[n>>8].life=rand()%100+70; + parts[n>>8].temp+=3000; + }*/ + + //Some elements should only be affected by wire/swch, or by a spark on inst/semiconductor + //So not affected by spark on metl, watr etc + if (is_elec) + { + if (((n&0xFF)==PT_METL || (n&0xFF)==PT_BMTL) && rand()%280==0) + { + parts[n>>8].temp = restrict_flt(parts[n>>8].temp+3000.0f, MIN_TEMP, MAX_TEMP); + } + if ((n&0xFF)==PT_BMTL && rand()%160==0) + { + sim->part_change_type(n>>8, rx+nx, ry+ny, PT_BMTL);//TODO: Redundant, was this meant to be BRMT or something? + parts[n>>8].temp = restrict_flt(parts[n>>8].temp+1000.0f, MIN_TEMP, MAX_TEMP); + } + if ((n&0xFF)==PT_METL && rand()%300==0) + { + sim->part_change_type(n>>8, rx+nx, ry+ny, PT_BMTL); + } + if ((n&0xFF)==PT_WIFI && rand()%8==0) + { + //Randomise channel + parts[n>>8].temp = rand()%MAX_TEMP; + } + if ((n&0xFF)==PT_WIFI && rand()%16==0) + { + sim->create_part(n>>8, rx+nx, ry+ny, PT_BREC); + parts[n>>8].temp = restrict_flt(parts[n>>8].temp+1000.0f, MIN_TEMP, MAX_TEMP); + } + } + if ((n&0xFF)==PT_SWCH && rand()%100==0) + { + sim->part_change_type(n>>8, rx+nx, ry+ny, PT_BREC); + } + if ((n&0xFF)==PT_SWCH && rand()%100==0) + { + parts[n>>8].temp = restrict_flt(parts[n>>8].temp+2000.0f, MIN_TEMP, MAX_TEMP); + } + if ((n&0xFF)==PT_ARAY && rand()%60==0) + { + sim->create_part(n>>8, rx+nx, ry+ny, PT_BREC); + parts[n>>8].temp = restrict_flt(parts[n>>8].temp+1000.0f, MIN_TEMP, MAX_TEMP); + } + if (t==PT_DLAY && rand()%70==0) + { + //Randomise delay + parts[n>>8].temp = (rand()%256) + 273.15f; + } + } + } + } + return 0; +} +int graphics_EMP(GRAPHICS_FUNC_ARGS) +{ + if(cpart->life) + { + *colr = cpart->life*1.5; + *colg = cpart->life*1.5; + *colb = 200-(cpart->life); + if (*colr>255) + *colr = 255; + if (*colg>255) + *colg = 255; + if (*colb>255) + *colb = 255; + if (*colb<=0) + *colb = 0; + } + return 0; +} diff --git a/src/elements/figh.cpp b/src/elements/figh.cpp new file mode 100644 index 0000000..8b18871 --- /dev/null +++ b/src/elements/figh.cpp @@ -0,0 +1,105 @@ +#include "element.h" + +int update_FIGH(UPDATE_FUNC_ARGS) +{ + playerst* figh = &sim->fighters[(unsigned char)parts[i].tmp]; + + float tarx, tary; + + parts[i].tmp2 = 0; //0 - stay in place, 1 - seek a stick man + + //Set target cords + if (sim->player.spwn) + { + if (sim->player2.spwn) + if ((pow(sim->player.legs[2]-x, 2) + pow(sim->player.legs[3]-y, 2))<= + (pow(sim->player2.legs[2]-x, 2) + pow(sim->player2.legs[3]-y, 2))) + { + tarx = sim->player.legs[2]; + tary = sim->player.legs[3]; + } + else + { + tarx = sim->player2.legs[2]; + tary = sim->player2.legs[3]; + } + else + { + tarx = sim->player.legs[2]; + tary = sim->player.legs[3]; + } + + parts[i].tmp2 = 1; + } + else + if (sim->player2.spwn) + { + tarx = sim->player2.legs[2]; + tary = sim->player2.legs[3]; + + parts[i].tmp2 = 1; + } + + switch (parts[i].tmp2) + { + case 1: + if ((pow(tarx-x, 2) + pow(tary-y, 2))<600) + { + if (figh->elem == PT_LIGH || figh->elem == PT_NEUT + || (sim->ptypes[figh->elem].properties&(PROP_DEADLY|PROP_RADIOACTIVE)) + || sim->ptypes[figh->elem].heat>=323 || sim->ptypes[figh->elem].heat<=243) + figh->comm = (int)figh->comm | 0x08; + } + else + if (tarx<x ) + { + if(!sim->eval_move(PT_DUST, figh->legs[4]-10, figh->legs[5]+6, NULL)) + figh->comm = 0x01; + else + figh->comm = 0x02; + + if (!sim->eval_move(PT_DUST, figh->legs[4]-4, figh->legs[5]-1, NULL) + || !sim->eval_move(PT_DUST, figh->legs[12]-4, figh->legs[13]-1, NULL) + || sim->eval_move(PT_DUST, 2*figh->legs[4]-figh->legs[6], figh->legs[5]+5, NULL)) + figh->comm = (int)figh->comm | 0x04; + } + else + { + if (!sim->eval_move(PT_DUST, figh->legs[12]+10, figh->legs[13]+6, NULL)) + figh->comm = 0x02; + else + figh->comm = 0x01; + + if (!sim->eval_move(PT_DUST, figh->legs[4]+4, figh->legs[5]-1, NULL) + || !sim->eval_move(PT_DUST, figh->legs[4]+4, figh->legs[5]-1, NULL) + || sim->eval_move(PT_DUST, 2*figh->legs[12]-figh->legs[14], figh->legs[13]+5, NULL)) + figh->comm = (int)figh->comm | 0x04; + } + break; + default: + figh->comm = 0; + break; + } + + figh->pcomm = figh->comm; + + run_stickman(figh, UPDATE_FUNC_SUBCALL_ARGS); + return 0; +} + +int graphics_FIGH(GRAPHICS_FUNC_ARGS) +{ + playerst * cplayer;// = &sim->fighters[(unsigned char)cpart->tmp]; + *pixel_mode = PSPEC_STICKMAN; + /*if (cplayer->elem<PT_NUM) + { + *colr = PIXR(sim->ptypes[cplayer->elem].pcolors); + *colg = PIXG(sim->ptypes[cplayer->elem].pcolors); + *colb = PIXB(sim->ptypes[cplayer->elem].pcolors); + } + else*/ + { + *colr = *colg = *colb = 255; + } + return 1; +} diff --git a/src/elements/fire.cpp b/src/elements/fire.cpp new file mode 100644 index 0000000..1f9c0c2 --- /dev/null +++ b/src/elements/fire.cpp @@ -0,0 +1,19 @@ +#include "element.h" + +int graphics_FIRE(GRAPHICS_FUNC_ARGS) +{ + int caddress = restrict_flt(restrict_flt((float)cpart->life, 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); + *colr = (unsigned char)ren->flm_data[caddress]; + *colg = (unsigned char)ren->flm_data[caddress+1]; + *colb = (unsigned char)ren->flm_data[caddress+2]; + + *firea = 255; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode = PMODE_NONE; //Clear default, don't draw pixel + *pixel_mode |= FIRE_ADD; + //Returning 0 means dynamic, do not cache + return 0; +} diff --git a/src/elements/firw.cpp b/src/elements/firw.cpp new file mode 100644 index 0000000..74605b0 --- /dev/null +++ b/src/elements/firw.cpp @@ -0,0 +1,65 @@ +#include "element.h" + +int update_FIRW(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, np; + if (parts[i].tmp==0) { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + rt = parts[r>>8].type; + if (rt==PT_FIRE||rt==PT_PLSM||rt==PT_THDR) + { + parts[i].tmp = 1; + parts[i].life = rand()%50+60; + } + } + } + else if (parts[i].tmp==1) { + if (parts[i].life==0) { + parts[i].tmp=2; + } else { + float newVel = parts[i].life/25; + parts[i].flags = parts[i].flags&0xFFFFFFFE; + /* TODO: + if ((pmap[(int)(ly-newVel)][(int)lx]&0xFF)==PT_NONE && ly-newVel>0) { + parts[i].vy = -newVel; + ly-=newVel; + iy-=newVel; + }*/ + parts[i].vy = -newVel; + } + } + else if (parts[i].tmp==2) { + int col = rand()%200+4; + int tmul; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + tmul = rand()%7; + np = sim->create_part(-1, x+rx, y+ry, PT_FIRW); + if (np>-1) + { + parts[np].vx = (rand()%3-1)*tmul; + parts[np].vy = (rand()%3-1)*tmul; + parts[np].tmp = col; + parts[np].life = rand()%100+100; + parts[np].temp = 6000.0f; + parts[np].dcolour = parts[i].dcolour; + } + } + sim->pv[y/CELL][x/CELL] += 20; + sim->kill_part(i); + return 1; + } else if (parts[i].tmp>=3) { + if (parts[i].life<=0) { + sim->kill_part(i); + return 1; + } + } + return 0; +} diff --git a/src/elements/fog.cpp b/src/elements/fog.cpp new file mode 100644 index 0000000..28952e9 --- /dev/null +++ b/src/elements/fog.cpp @@ -0,0 +1,22 @@ +#include "element.h" + +int update_FOG(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->ptypes[r&0xFF].state==ST_SOLID&&5>=rand()%50&&parts[i].life==0&&!((r&0xFF)==PT_CLNE||(r&0xFF)==PT_PCLN)) // TODO: should this also exclude BCLN? + { + sim->part_change_type(i,x,y,PT_RIME); + } + if ((r&0xFF)==PT_SPRK) + { + parts[i].life += rand()%20; + } + } + return 0; +} diff --git a/src/elements/frzw.cpp b/src/elements/frzw.cpp new file mode 100644 index 0000000..932bccb --- /dev/null +++ b/src/elements/frzw.cpp @@ -0,0 +1,30 @@ +#include "element.h" + +int update_FRZW(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR&&5>rand()%70) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_FRZW); + } + } + if (parts[i].life==0&&13>rand()%2500) + { + sim->part_change_type(i,x,y,PT_ICEI); + parts[i].ctype=PT_FRZW; + parts[i].temp = restrict_flt(parts[i].temp-200.0f, MIN_TEMP, MAX_TEMP); + } + else if ((100-(parts[i].life))>rand()%50000) + { + sim->part_change_type(i,x,y,PT_ICEI); + parts[i].ctype=PT_FRZW; + parts[i].temp = restrict_flt(parts[i].temp-200.0f, MIN_TEMP, MAX_TEMP); + } + return 0; +} diff --git a/src/elements/frzz.cpp b/src/elements/frzz.cpp new file mode 100644 index 0000000..8e09c1d --- /dev/null +++ b/src/elements/frzz.cpp @@ -0,0 +1,25 @@ +#include "element.h" + +int update_FRZZ(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR&&5>rand()%100) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_FRZW); + parts[r>>8].life = 100; + parts[i].type = PT_NONE; + } + + } + if (parts[i].type==PT_NONE) { + sim->kill_part(i); + return 1; + } + return 0; +} diff --git a/src/elements/fsep.cpp b/src/elements/fsep.cpp new file mode 100644 index 0000000..3db5ba5 --- /dev/null +++ b/src/elements/fsep.cpp @@ -0,0 +1,35 @@ +#include "element.h" + +int update_FSEP(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life<=0) { + r = sim->create_part(i, x, y, PT_PLSM); + if (r!=-1) + parts[r].life = 50; + return 1; + } else if (parts[i].life < 40) { + parts[i].life--; + if ((rand()%10)==0) { + r = sim->create_part(-1, (rx=x+rand()%3-1), (ry=y+rand()%3-1), PT_PLSM); + if (r!=-1) + parts[r].life = 50; + } + } + else { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_SPRK || (parts[i].temp>=(273.15+400.0f))) && 1>(rand()%15)) + { + if (parts[i].life>40) { + parts[i].life = 39; + } + } + } + } + return 0; +} diff --git a/src/elements/fuse.cpp b/src/elements/fuse.cpp new file mode 100644 index 0000000..e1db1ff --- /dev/null +++ b/src/elements/fuse.cpp @@ -0,0 +1,41 @@ +#include "element.h" + +int update_FUSE(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life<=0) { + r = sim->create_part(i, x, y, PT_PLSM); + if (r!=-1) + parts[r].life = 50; + return 1; + } else if (parts[i].life < 40) { + parts[i].life--; + if ((rand()%100)==0) { + r = sim->create_part(-1, (rx=x+rand()%3-1), (ry=y+rand()%3-1), PT_PLSM); + if (r!=-1) + parts[r].life = 50; + } + } + if ((sim->pv[y/CELL][x/CELL] > 2.7f)&&parts[i].tmp>40) + parts[i].tmp=39; + else if (parts[i].tmp<40&&parts[i].tmp>0) + parts[i].tmp--; + else if (parts[i].tmp<=0) { + sim->create_part(i, x, y, PT_FSEP); + return 1; + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK || ((parts[i].temp>=(273.15+700.0f)) && 1>(rand()%20))) + { + if (parts[i].life>40) { + parts[i].life = 39; + } + } + } + return 0; +} diff --git a/src/elements/fwrk.cpp b/src/elements/fwrk.cpp new file mode 100644 index 0000000..d217ad9 --- /dev/null +++ b/src/elements/fwrk.cpp @@ -0,0 +1,53 @@ +#include "element.h" + +int update_FWRK(UPDATE_FUNC_ARGS) { + int r, rx, ry, np; + if ((parts[i].temp>400&&(9+parts[i].temp/40)>rand()%100000&&parts[i].life==0&&!pmap[y-1][x])||parts[i].ctype==PT_DUST) + { + np = sim->create_part(-1, x , y-1 , PT_FWRK); + if (np!=-1) + { + parts[np].vy = rand()%8-22; + parts[np].vx = rand()%20-rand()%20; + parts[np].life=rand()%15+25; + parts[np].dcolour = parts[i].dcolour; + sim->kill_part(i); + return 1; + } + } + if (parts[i].life>=45) + parts[i].life=0; + if ((parts[i].life<3&&parts[i].life>0)||(parts[i].vy>6&&parts[i].life>0)) + { + int q = (rand()%255+1); + int w = (rand()%255+1); + int e = (rand()%255+1); + for (rx=-1; rx<2; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + if (5>=rand()%8) + { + if (!pmap[y+ry][x+rx]) + { + np = sim->create_part(-1, x+rx, y+ry , PT_DUST); + sim->pv[y/CELL][x/CELL] += 2.00f*CFDS; + if (np!=-1) + { + parts[np].vy = -(rand()%10-1); + parts[np].vx = ((rand()%2)*2-1)*rand()%(5+5)+(parts[i].vx)*2 ; + parts[np].life= rand()%37+18; + parts[np].tmp=q; + parts[np].flags=w; + parts[np].ctype=e; + parts[np].temp= rand()%20+6000; + parts[np].dcolour = parts[i].dcolour; + } + } + } + } + sim->kill_part(i); + return 1; + } + return 0; +} diff --git a/src/elements/gbmb.cpp b/src/elements/gbmb.cpp new file mode 100644 index 0000000..95afc4e --- /dev/null +++ b/src/elements/gbmb.cpp @@ -0,0 +1,26 @@ +#include "element.h" +int update_GBMB(UPDATE_FUNC_ARGS) { + int rx,ry,r; + if (parts[i].life<=0) + { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + { + r = pmap[y+ry][x+rx]; + if(!r) + continue; + if((r&0xFF)!=PT_BOMB && (r&0xFF)!=PT_GBMB && + (r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_DMND) + { + parts[i].life=60; + break; + } + } + } + if(parts[i].life>20) + sim->gravmap[(y/CELL)*(XRES/CELL)+(x/CELL)] = 20; + if(parts[i].life<20 && parts[i].life>=1) + sim->gravmap[(y/CELL)*(XRES/CELL)+(x/CELL)] = -80; + return 0; +} diff --git a/src/elements/glas.cpp b/src/elements/glas.cpp new file mode 100644 index 0000000..e8c0a6c --- /dev/null +++ b/src/elements/glas.cpp @@ -0,0 +1,11 @@ +#include "element.h" + +int update_GLAS(UPDATE_FUNC_ARGS) { + parts[i].pavg[0] = parts[i].pavg[1]; + parts[i].pavg[1] = sim->pv[y/CELL][x/CELL]; + if (parts[i].pavg[1]-parts[i].pavg[0] > 0.25f || parts[i].pavg[1]-parts[i].pavg[0] < -0.25f) + { + sim->part_change_type(i,x,y,PT_BGLA); + } + return 0; +} diff --git a/src/elements/glow.cpp b/src/elements/glow.cpp new file mode 100644 index 0000000..e83e2f4 --- /dev/null +++ b/src/elements/glow.cpp @@ -0,0 +1,28 @@ +#include "element.h" + +int update_GLOW(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR&&5>(rand()%2000)) + { + parts[i].type = PT_NONE; + sim->part_change_type(r>>8,x+rx,y+ry,PT_DEUT); + parts[r>>8].life = 10; + } + } + parts[i].ctype = sim->pv[y/CELL][x/CELL]*16; + + parts[i].tmp = abs((int)((sim->vx[y/CELL][x/CELL]+sim->vy[y/CELL][x/CELL])*16.0f)) + abs((int)((parts[i].vx+parts[i].vy)*64.0f)); + //printf("%f %f\n", parts[i].vx, parts[i].vy); + if (parts[i].type==PT_NONE) { + sim->kill_part(i); + return 1; + } + return 0; +} diff --git a/src/elements/goo.cpp b/src/elements/goo.cpp new file mode 100644 index 0000000..c305182 --- /dev/null +++ b/src/elements/goo.cpp @@ -0,0 +1,13 @@ +#include "element.h" + +int update_GOO(UPDATE_FUNC_ARGS) { + if (!parts[i].life && sim->pv[y/CELL][x/CELL]>1.0f) + parts[i].life = rand()%80+300; + if (parts[i].life) + { + float advection = 0.1f; + parts[i].vx += advection*sim->vx[y/CELL][x/CELL]; + parts[i].vy += advection*sim->vy[y/CELL][x/CELL]; + } + return 0; +} diff --git a/src/elements/gpmp.cpp b/src/elements/gpmp.cpp new file mode 100644 index 0000000..dcde7a9 --- /dev/null +++ b/src/elements/gpmp.cpp @@ -0,0 +1,34 @@ +#include "element.h" + +int update_GPMP(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + if (parts[i].life==10) + { + if (parts[i].temp>=256.0+273.15) + parts[i].temp=256.0+273.15; + if (parts[i].temp<= -256.0+273.15) + parts[i].temp = -256.0+273.15; + + sim->gravmap[(y/CELL)*(XRES/CELL)+(x/CELL)] = 0.2f*(parts[i].temp-273.15); + if (y+CELL<YRES && sim->pv[y/CELL+1][x/CELL]<(parts[i].temp-273.15)) + sim->gravmap[(y/CELL+1)*(XRES/CELL)+(x/CELL)] += 0.1f*((parts[i].temp-273.15)-sim->gravmap[(y/CELL+1)*(XRES/CELL)+(x/CELL)]); + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_GPMP) + { + if (parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[r>>8].life==0) + parts[r>>8].life = 10; + } + } + } + return 0; +} diff --git a/src/elements/graphics_default.cpp b/src/elements/graphics_default.cpp new file mode 100644 index 0000000..1270977 --- /dev/null +++ b/src/elements/graphics_default.cpp @@ -0,0 +1,23 @@ +#include "element.h" + +int graphics_DEFAULT(GRAPHICS_FUNC_ARGS) +{ + int t = cpart->type; + //Property based defaults + if(ren->sim->ptypes[t].properties & PROP_RADIOACTIVE) *pixel_mode |= PMODE_GLOW; + if(ren->sim->ptypes[t].properties & TYPE_LIQUID) + { + *pixel_mode |= PMODE_BLUR; + } + if(ren->sim->ptypes[t].properties & TYPE_GAS) + { + *pixel_mode &= ~PMODE; + *pixel_mode |= FIRE_BLEND; + *firer = *colr/2; + *fireg = *colg/2; + *fireb = *colb/2; + *firea = 125; + *pixel_mode |= DECO_FIRE; + } + return 1; +} diff --git a/src/elements/h2.cpp b/src/elements/h2.cpp new file mode 100644 index 0000000..da39ad0 --- /dev/null +++ b/src/elements/h2.cpp @@ -0,0 +1,34 @@ +#include "element.h" + +int update_H2(UPDATE_FUNC_ARGS) +{ + int r,rx,ry,rt; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + rt = (r&0xFF); + if (!r) + continue; + if (sim->pv[y/CELL][x/CELL] > 8.0f && rt == PT_DESL) // This will not work. DESL turns to fire above 5.0 pressure + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_WATR); + sim->part_change_type(i,x,y,PT_OIL); + } + if ((r&0xFF)==PT_FIRE) + { + parts[r>>8].temp=2473.15; + if(parts[r>>8].tmp&0x02) + parts[r>>8].temp=3473; + parts[r>>8].tmp |= 1; + } + if ((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM || (r&0xFF)==PT_LAVA) + { + sim->create_part(i,x,y,PT_FIRE); + parts[i].temp+=(rand()/(RAND_MAX/100)); + parts[i].tmp |= 1; + } + } + return 0; +} diff --git a/src/elements/hswc.cpp b/src/elements/hswc.cpp new file mode 100644 index 0000000..c727395 --- /dev/null +++ b/src/elements/hswc.cpp @@ -0,0 +1,26 @@ +#include "element.h" + +int update_HSWC(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + if (parts[i].life==10) + { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_HSWC) + { + if (parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[r>>8].life==0) + parts[r>>8].life = 10; + } + } + } + return 0; +} diff --git a/src/elements/ice.cpp b/src/elements/ice.cpp new file mode 100644 index 0000000..aece17b --- /dev/null +++ b/src/elements/ice.cpp @@ -0,0 +1,23 @@ +#include "element.h" + +int update_ICEI(UPDATE_FUNC_ARGS) { //currently used for snow as well + int r, rx, ry; + if (parts[i].ctype==PT_FRZW)//get colder if it is from FRZW + { + parts[i].temp = restrict_flt(parts[i].temp-1.0f, MIN_TEMP, MAX_TEMP); + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_SALT || (r&0xFF)==PT_SLTW) && 1>(rand()%1000)) + { + sim->part_change_type(i,x,y,PT_SLTW); + sim->part_change_type(r>>8,x+rx,y+ry,PT_SLTW); + } + } + return 0; +} diff --git a/src/elements/ignt.cpp b/src/elements/ignt.cpp new file mode 100644 index 0000000..1d7ea64 --- /dev/null +++ b/src/elements/ignt.cpp @@ -0,0 +1,44 @@ +#include "element.h" + +int update_IGNT(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if(parts[i].tmp==0) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM) + { + parts[i].tmp = 1; + } + else if ((r&0xFF)==PT_SPRK || (r&0xFF)==PT_LIGH || ((r&0xFF)==PT_IGNT && parts[r>>8].life==1)) + { + parts[i].tmp = 1; + } + } + } + else if(parts[i].life > 0) + { + if(rand()%3) + { + int nb = sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, PT_BOMB); + if (nb!=-1) { + parts[nb].tmp = 1; + parts[nb].life = 30; + parts[nb].vx = rand()%20-10; + parts[nb].vy = rand()%20-10; + parts[nb].temp = restrict_flt(400.0f+parts[i].temp-273.15, MIN_TEMP, MAX_TEMP); + } + } + else + { + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, PT_FIRE); + } + parts[i].life--; + } + return 0; +} diff --git a/src/elements/iron.cpp b/src/elements/iron.cpp new file mode 100644 index 0000000..b887cf8 --- /dev/null +++ b/src/elements/iron.cpp @@ -0,0 +1,25 @@ +#include "element.h" + +int update_IRON(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((((r&0xFF) == PT_SALT && 15>(rand()/(RAND_MAX/700))) || + ((r&0xFF) == PT_SLTW && 30>(rand()/(RAND_MAX/2000))) || + ((r&0xFF) == PT_WATR && 5 >(rand()/(RAND_MAX/6000))) || + ((r&0xFF) == PT_O2 && 2 >(rand()/(RAND_MAX/500))) || + ((r&0xFF) == PT_LO2))&& + (!(parts[i].life)) + ) + { + sim->part_change_type(i,x,y,PT_BMTL); + parts[i].tmp=(rand()/(RAND_MAX/10))+20; + } + } + return 0; +} diff --git a/src/elements/isz.cpp b/src/elements/isz.cpp new file mode 100644 index 0000000..25446d2 --- /dev/null +++ b/src/elements/isz.cpp @@ -0,0 +1,14 @@ +#include "element.h" + +int update_ISZ(UPDATE_FUNC_ARGS) { // for both ISZS and ISOZ + float rr, rrr; + if (1>rand()%200 && ((int)(-4.0f*(sim->pv[y/CELL][x/CELL])))>(rand()%1000)) + { + sim->create_part(i, x, y, PT_PHOT); + rr = (rand()%228+128)/127.0f; + rrr = (rand()%360)*3.14159f/180.0f; + parts[i].vx = rr*cosf(rrr); + parts[i].vy = rr*sinf(rrr); + } + return 0; +} diff --git a/src/elements/lava.cpp b/src/elements/lava.cpp new file mode 100644 index 0000000..3d7827b --- /dev/null +++ b/src/elements/lava.cpp @@ -0,0 +1,19 @@ +#include "element.h" + +int graphics_LAVA(GRAPHICS_FUNC_ARGS) +{ + *colr = cpart->life * 2 + 0xE0; + *colg = cpart->life * 1 + 0x50; + *colb = cpart->life / 2 + 0x10; + if (*colr>255) *colr = 255; + if (*colg>192) *colg = 192; + if (*colb>128) *colb = 128; + *firea = 40; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + *pixel_mode |= FIRE_ADD; + *pixel_mode |= PMODE_BLUR; + //Returning 0 means dynamic, do not cache + return 0; +} diff --git a/src/elements/lcry.cpp b/src/elements/lcry.cpp new file mode 100644 index 0000000..546c2ca --- /dev/null +++ b/src/elements/lcry.cpp @@ -0,0 +1,61 @@ +#include "element.h" + +int update_LCRY(UPDATE_FUNC_ARGS) +{ + int r, rx, ry; + if(parts[i].tmp==1 || parts[i].tmp==0) + { + if(parts[i].tmp==1) + { + if(parts[i].life<=0) + parts[i].tmp = 0; + else + { + parts[i].life-=2; + if(parts[i].life < 0) + parts[i].life = 0; + parts[i].tmp2 = parts[i].life; + } + } + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_LCRY && parts[r>>8].tmp == 3) + { + parts[r>>8].tmp = 1; + } + } + } + else if(parts[i].tmp==2 || parts[i].tmp==3) + { + if(parts[i].tmp==2) + { + if(parts[i].life>=10) + parts[i].tmp = 3; + else + { + parts[i].life+=2; + if(parts[i].life > 10) + parts[i].life = 10; + parts[i].tmp2 = parts[i].life; + } + } + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_LCRY && parts[r>>8].tmp == 0) + { + parts[r>>8].tmp = 2; + } + } + } + return 0; +} diff --git a/src/elements/legacy.cpp b/src/elements/legacy.cpp new file mode 100644 index 0000000..dd58173 --- /dev/null +++ b/src/elements/legacy.cpp @@ -0,0 +1,120 @@ +#include "element.h" + +// Interactions which only occur when legacy_enable is on +int update_legacy_all(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt; + int t = parts[i].type; + if (!sim->legacy_enable) return 0; + if (t==PT_WTRV) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && + x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_WATR||(r&0xFF)==PT_DSTW||(r&0xFF)==PT_SLTW) && 1>(rand()%1000)) + { + sim->part_change_type(i,x,y,PT_WATR); + sim->part_change_type(r>>8,x+rx,y+ry,PT_WATR); + } + if (((r&0xFF)==PT_ICEI || (r&0xFF)==PT_SNOW) && 1>(rand()%1000)) + { + sim->part_change_type(i,x,y,PT_WATR); + if (1>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_WATR); + } + } + } + else if (t==PT_WATR) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && + x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_LAVA) && 1>(rand()%10)) + { + sim->part_change_type(i,x,y,PT_WTRV); + } + } + } + else if (t==PT_SLTW) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && + x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_LAVA) && 1>(rand()%10)) + { + sim->part_change_type(i,x,y,PT_SALT); + sim->part_change_type(r>>8,x+rx,y+ry,PT_WTRV); + } + } + } + else if (t==PT_DSTW) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && + x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_LAVA) && 1>(rand()%10)) + { + sim->part_change_type(i,x,y,PT_WTRV); + } + } + } + else if (t==PT_ICEI) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_WATR || (r&0xFF)==PT_DSTW) && 1>(rand()%1000)) + { + sim->part_change_type(i,x,y,PT_ICEI); + sim->part_change_type(r>>8,x+rx,y+ry,PT_ICEI); + } + } + } + else if (t==PT_SNOW) { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_WATR || (r&0xFF)==PT_DSTW) && 1>(rand()%1000)) + { + sim->part_change_type(i,x,y,PT_ICEI); + sim->part_change_type(r>>8,x+rx,y+ry,PT_ICEI); + } + if (((r&0xFF)==PT_WATR || (r&0xFF)==PT_DSTW) && 15>(rand()%1000)) + sim->part_change_type(i,x,y,PT_WATR); + } + } + if (t==PT_WTRV && sim->pv[y/CELL][x/CELL]>4.0f) + sim->part_change_type(i,x,y,PT_DSTW); + if (t==PT_OIL && sim->pv[y/CELL][x/CELL]<-6.0f) + sim->part_change_type(i,x,y,PT_GAS); + if (t==PT_GAS && sim->pv[y/CELL][x/CELL]>6.0f) + sim->part_change_type(i,x,y,PT_OIL); + if (t==PT_DESL && sim->pv[y/CELL][x/CELL]>12.0f) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = rand()%50+120; + } + return 0; +} diff --git a/src/elements/ligh.cpp b/src/elements/ligh.cpp new file mode 100644 index 0000000..8108c4b --- /dev/null +++ b/src/elements/ligh.cpp @@ -0,0 +1,295 @@ +#include "element.h" + +#define LIGHTING_POWER 0.65 + +int LIGH_nearest_part(Simulation * sim, int ci, int max_d) +{ + int distance = (max_d!=-1)?max_d:MAX_DISTANCE; + int ndistance = 0; + int id = -1; + int i = 0; + int cx = (int)sim->parts[ci].x; + int cy = (int)sim->parts[ci].y; + for (i=0; i<=sim->parts_lastActiveIndex; i++) + { + if (sim->parts[i].type && sim->parts[i].life && i!=ci && sim->parts[i].type!=PT_LIGH && sim->parts[i].type!=PT_THDR && sim->parts[i].type!=PT_NEUT && sim->parts[i].type!=PT_PHOT) + { + ndistance = abs(cx-sim->parts[i].x)+abs(cy-sim->parts[i].y);// Faster but less accurate Older: sqrt(pow(cx-parts[i].x, 2)+pow(cy-parts[i].y, 2)); + if (ndistance<distance) + { + distance = ndistance; + id = i; + } + } + } + return id; +} + +int contact_part(Simulation * sim, int i, int tp) +{ + int x=sim->parts[i].x, y=sim->parts[i].y; + int r,rx,ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = sim->pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==tp) + return r>>8; + } + return -1; +} + +void create_line_par(Simulation * sim, int x1, int y1, int x2, int y2, int c, int temp, int life, int tmp, int tmp2) +{ + int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy; + float e, de; + if (c==WL_EHOLE || c==WL_ALLOWGAS || c==WL_ALLOWALLELEC || c==WL_ALLOWSOLID || c==WL_ALLOWAIR || c==WL_WALL || c==WL_DESTROYALL || c==WL_ALLOWLIQUID || c==WL_FAN || c==WL_STREAM || c==WL_DETECT || c==WL_EWALL || c==WL_WALLELEC) + return; // this function only for particles, no walls + if (cp) + { + y = x1; + x1 = y1; + y1 = y; + y = x2; + x2 = y2; + y2 = y; + } + if (x1 > x2) + { + y = x1; + x1 = x2; + x2 = y; + y = y1; + y1 = y2; + y2 = y; + } + dx = x2 - x1; + dy = abs(y2 - y1); + e = 0.0f; + if (dx) + de = dy/(float)dx; + else + de = 0.0f; + y = y1; + sy = (y1<y2) ? 1 : -1; + for (x=x1; x<=x2; x++) + { + int p; + if (cp) + p = sim->create_part(-1, y, x, c); + else + p = sim->create_part(-1, x, y,c); + if (p!=-1) + { + sim->parts[p].life = life; + sim->parts[p].temp = temp; + sim->parts[p].tmp = tmp; + sim->parts[p].tmp2 = tmp2; + } + e += de; + if (e >= 0.5f) + { + y += sy; + e -= 1.0f; + } + } +} + +int update_LIGH(UPDATE_FUNC_ARGS) +{ + /* + * + * tmp2: + * -1 - part will be removed + * 0 - "branches" of the lightning + * 1 - bending + * 2 - branching + * 3 - transfer spark or make destruction + * 4 - first pixel + * + * life - "thickness" of lighting (but anyway one pixel) + * + * tmp - angle of lighting + * + */ + int r,rx,ry, multipler, powderful; + float angle, angle2=-1; + int pNear = 0; + powderful = powderful = parts[i].temp*(1+parts[i].life/40)*LIGHTING_POWER; + update_PYRO(UPDATE_FUNC_SUBCALL_ARGS); + if (sim->aheat_enable) + { + sim->hv[y/CELL][x/CELL]+=powderful/50; + if (sim->hv[y/CELL][x/CELL]>MAX_TEMP) + sim->hv[y/CELL][x/CELL]=MAX_TEMP; + } + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_LIGH && (r&0xFF)!=PT_TESC) + { + if ((r&0xFF)!=PT_CLNE&&(r&0xFF)!=PT_THDR&&(r&0xFF)!=PT_DMND&&(r&0xFF)!=PT_FIRE&&(r&0xFF)!=PT_NEUT&&(r&0xFF)!=PT_PHOT) + { + if ((sim->ptypes[r&0xFF].properties&PROP_CONDUCTS) && parts[r>>8].life==0) + { + sim->create_part(r>>8,x+rx,y+ry,PT_SPRK); + } + sim->pv[y/CELL][x/CELL] += powderful/400; + if (sim->ptypes[r&0xFF].hconduct) parts[r>>8].temp = restrict_flt(parts[r>>8].temp+powderful/1.5, MIN_TEMP, MAX_TEMP); + } + if ((r&0xFF)==PT_DEUT || (r&0xFF)==PT_PLUT) // start nuclear reactions + { + parts[r>>8].temp = restrict_flt(parts[r>>8].temp+powderful, MIN_TEMP, MAX_TEMP); + sim->pv[y/CELL][x/CELL] +=powderful/35; + if (rand()%3==0) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_NEUT); + parts[r>>8].life = rand()%480+480; + parts[r>>8].vx=rand()%10-5; + parts[r>>8].vy=rand()%10-5; + } + } + if ((r&0xFF)==PT_COAL || (r&0xFF)==PT_BCOL) // ignite coal + { + if (parts[r>>8].life>100) { + parts[r>>8].life = 99; + } + } + if (sim->ptypes[r&0xFF].hconduct) + parts[r>>8].temp = restrict_flt(parts[r>>8].temp+powderful/10, MIN_TEMP, MAX_TEMP); + if (((r&0xFF)==PT_STKM && sim->player.elem!=PT_LIGH) || ((r&0xFF)==PT_STKM2 && sim->player2.elem!=PT_LIGH)) + { + parts[r>>8].life-=powderful/100; + } + } + } + if (parts[i].tmp2==3) + { + parts[i].tmp2=0; + return 1; + } + + if (parts[i].tmp2==-1) + { + sim->kill_part(i); + return 1; + } + if (parts[i].tmp2<=0 || parts[i].life<=1) + { + if (parts[i].tmp2>0) + parts[i].tmp2=0; + parts[i].tmp2--; + return 1; + } + if (parts[i].tmp2<=-2) + { + sim->kill_part(i); + return 1; + } + + angle2=-1; + + pNear = LIGH_nearest_part(sim, i, parts[i].life*2.5); + if (pNear!=-1) + { + int t=parts[pNear].type; + float n_angle; // angle to nearest part + rx=parts[pNear].x-x; + ry=parts[pNear].y-y; + if (rx*rx+ry*ry!=0) + n_angle = asin(-ry/sqrt(rx*rx+ry*ry)); + else + n_angle = 0; + if (n_angle<0) + n_angle+=M_PI*2; + if (parts[i].life<5 || fabs(n_angle-parts[i].tmp*M_PI/180)<M_PI*0.8) // lightning strike + { + create_line_par(sim, x, y, x+rx, y+ry, PT_LIGH, parts[i].temp, parts[i].life, parts[i].tmp-90, 0); + + if (t!=PT_TESC) + { + pNear=contact_part(sim, pNear, PT_LIGH); + if (pNear!=-1) + { + parts[pNear].tmp2=3; + parts[pNear].life=(int)(1.0*parts[i].life/2-1); + parts[pNear].tmp=parts[i].tmp-180; + parts[pNear].temp=parts[i].temp; + } + } + } + else pNear=-1; + } + + //if (parts[i].tmp2==1/* || near!=-1*/) + //angle=0;//parts[i].tmp-30+rand()%60; + angle = parts[i].tmp-30+rand()%60; + if (angle<0) + angle+=360; + if (angle>=360) + angle-=360; + if (parts[i].tmp2==2 && pNear==-1) + { + angle2=angle+100-rand()%200; + if (angle2<0) + angle2+=360; + if (angle2>=360) + angle-=360; + } + + multipler=parts[i].life*1.5+rand()%((int)(parts[i].life+1)); + rx=cos(angle*M_PI/180)*multipler; + ry=-sin(angle*M_PI/180)*multipler; + create_line_par(sim, x, y, x+rx, y+ry, PT_LIGH, parts[i].temp, parts[i].life, angle, 0); + + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((r&0xFF)==PT_LIGH) + { + parts[r>>8].tmp2=1+(rand()%200>parts[i].tmp2*parts[i].tmp2/10+60); + parts[r>>8].life=(int)(1.0*parts[i].life/1.5-rand()%2); + parts[r>>8].tmp=angle; + parts[r>>8].temp=parts[i].temp; + } + } + + if (angle2!=-1) + { + multipler=parts[i].life*1.5+rand()%((int)(parts[i].life+1)); + rx=cos(angle2*M_PI/180)*multipler; + ry=-sin(angle2*M_PI/180)*multipler; + create_line_par(sim, x, y, x+rx, y+ry, PT_LIGH, parts[i].temp, parts[i].life, angle2, 0); + + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((r&0xFF)==PT_LIGH) + { + parts[r>>8].tmp2=1+(rand()%200>parts[i].tmp2*parts[i].tmp2/10+40); + parts[r>>8].life=(int)(1.0*parts[i].life/1.5-rand()%2); + parts[r>>8].tmp=angle; + parts[r>>8].temp=parts[i].temp; + } + } + } + + parts[i].tmp2=-1; + return 1; +} +int graphics_LIGH(GRAPHICS_FUNC_ARGS) +{ + *colr = 235; + *colg = 245; + *colb = 255; + *pixel_mode |= PMODE_GLOW; + return 1; +} diff --git a/src/elements/merc.cpp b/src/elements/merc.cpp new file mode 100644 index 0000000..2df113b --- /dev/null +++ b/src/elements/merc.cpp @@ -0,0 +1,70 @@ +#include "element.h" + +int update_MERC(UPDATE_FUNC_ARGS) { + int r, rx, ry, trade, np; + int maxtmp = ((10000/(parts[i].temp + 1))-1); + if ((10000%((int)parts[i].temp+1))>rand()%((int)parts[i].temp+1)) + maxtmp ++; + if (parts[i].tmp < maxtmp) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r || (parts[i].tmp >=maxtmp)) + continue; + if ((r&0xFF)==PT_MERC&&33>=rand()/(RAND_MAX/100)+1) + { + if ((parts[i].tmp + parts[r>>8].tmp + 1) <= maxtmp) + { + parts[i].tmp += parts[r>>8].tmp + 1; + sim->kill_part(r>>8); + } + } + } + } + else + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (parts[i].tmp<=maxtmp) + continue; + if ((!r)&&parts[i].tmp>=1)//if nothing then create deut + { + np = sim->create_part(-1,x+rx,y+ry,PT_MERC); + if (np<0) continue; + parts[i].tmp--; + parts[np].temp = parts[i].temp; + parts[np].tmp = 0; + } + } + for ( trade = 0; trade<4; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_MERC&&(parts[i].tmp>parts[r>>8].tmp)&&parts[i].tmp>0)//diffusion + { + int temp = parts[i].tmp - parts[r>>8].tmp; + if (temp ==1) + { + parts[r>>8].tmp ++; + parts[i].tmp --; + } + else if (temp>0) + { + parts[r>>8].tmp += temp/2; + parts[i].tmp -= temp/2; + } + } + } + } + return 0; +} diff --git a/src/elements/mort.cpp b/src/elements/mort.cpp new file mode 100644 index 0000000..bbb6264 --- /dev/null +++ b/src/elements/mort.cpp @@ -0,0 +1,6 @@ +#include "element.h" + +int update_MORT(UPDATE_FUNC_ARGS) { + sim->create_part(-1, x, y-1, PT_SMKE); + return 0; +} diff --git a/src/elements/nbhl.cpp b/src/elements/nbhl.cpp new file mode 100644 index 0000000..056313c --- /dev/null +++ b/src/elements/nbhl.cpp @@ -0,0 +1,6 @@ +#include "element.h" + +int update_NBHL(UPDATE_FUNC_ARGS) { + sim->gravmap[(y/CELL)*(XRES/CELL)+(x/CELL)] += 0.1f; + return 0; +} diff --git a/src/elements/neut.cpp b/src/elements/neut.cpp new file mode 100644 index 0000000..a48fc09 --- /dev/null +++ b/src/elements/neut.cpp @@ -0,0 +1,145 @@ +#include "element.h" + + +int create_n_parts(Simulation * sim, int n, int x, int y, float vx, float vy, float temp, int t)//testing a new deut create part +{ + int i, c; + n = (n/50); + if (n<1) { + n = 1; + } + if (n>340) { + n = 340; + } + if (x<0 || y<0 || x>=XRES || y>=YRES || t<0 || t>=PT_NUM) + return -1; + + for (c=0; c<n; c++) { + float r = (rand()%128+128)/127.0f; + float a = (rand()%360)*M_PI/180.0f; + if (sim->pfree == -1) + return -1; + i = sim->pfree; + sim->pfree = sim->parts[i].life; + if (i>sim->parts_lastActiveIndex) sim->parts_lastActiveIndex = i; + + sim->parts[i].x = (float)x; + sim->parts[i].y = (float)y; + sim->parts[i].type = t; + sim->parts[i].life = rand()%480+480; + sim->parts[i].vx = r*cosf(a); + sim->parts[i].vy = r*sinf(a); + sim->parts[i].ctype = 0; + sim->parts[i].temp = temp; + sim->parts[i].tmp = 0; + if (t!=PT_STKM&&t!=PT_STKM2 && t!=PT_PHOT && t!=PT_NEUT && !sim->pmap[y][x]) + sim->pmap[y][x] = t|(i<<8); + else if ((t==PT_PHOT||t==PT_NEUT) && !sim->photons[y][x]) + sim->photons[y][x] = t|(i<<8); + + sim->pv[y/CELL][x/CELL] += 6.0f * CFDS; + } + return 0; +} + +int update_NEUT(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt; + int pressureFactor = 3 + (int)sim->pv[y/CELL][x/CELL]; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR || (r&0xFF)==PT_ICEI || (r&0xFF)==PT_SNOW) + { + parts[i].vx *= 0.995; + parts[i].vy *= 0.995; + } + if ((r&0xFF)==PT_PLUT && pressureFactor>(rand()%1000)) + { + if (33>rand()%100) + { + sim->create_part(r>>8, x+rx, y+ry, rand()%3 ? PT_LAVA : PT_URAN); + parts[r>>8].temp = MAX_TEMP; + if (parts[r>>8].type==PT_LAVA) { + parts[r>>8].tmp = 100; + parts[r>>8].ctype = PT_PLUT; + } + } + else + { + sim->create_part(r>>8, x+rx, y+ry, PT_NEUT); + parts[r>>8].vx = 0.25f*parts[r>>8].vx + parts[i].vx; + parts[r>>8].vy = 0.25f*parts[r>>8].vy + parts[i].vy; + } + sim->pv[y/CELL][x/CELL] += 10.0f * CFDS; //Used to be 2, some people said nukes weren't powerful enough + update_PYRO(UPDATE_FUNC_SUBCALL_ARGS); + } +#ifdef SDEUT + else if ((r&0xFF)==PT_DEUT && (pressureFactor+1+(parts[r>>8].life/100))>(rand()%1000)) + { + create_n_parts(sim, parts[r>>8].life, x+rx, y+ry, parts[i].vx, parts[i].vy, restrict_flt(parts[r>>8].temp + parts[r>>8].life*500, MIN_TEMP, MAX_TEMP), PT_NEUT); + sim->kill_part(r>>8); + } +#else + else if ((r&0xFF)==PT_DEUT && (pressureFactor+1)>(rand()%1000)) + { + create_part(r>>8, x+rx, y+ry, PT_NEUT); + parts[r>>8].vx = 0.25f*parts[r>>8].vx + parts[i].vx; + parts[r>>8].vy = 0.25f*parts[r>>8].vy + parts[i].vy; + if (parts[r>>8].life>0) + { + parts[r>>8].life --; + parts[r>>8].temp = restrict_flt(parts[r>>8].temp + parts[r>>8].life*17, MIN_TEMP, MAX_TEMP); + pv[y/CELL][x/CELL] += 6.0f * CFDS; + } + else + sim.kill_part(r>>8); + } +#endif + else if ((r&0xFF)==PT_GUNP && 15>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_DUST); + else if ((r&0xFF)==PT_DYST && 15>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_YEST); + else if ((r&0xFF)==PT_YEST) + sim->part_change_type(r>>8,x+rx,y+ry,PT_DYST); + else if ((r&0xFF)==PT_WATR && 15>(rand()%100)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_DSTW); + else if ((r&0xFF)==PT_PLEX && 15>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_GOO); + else if ((r&0xFF)==PT_NITR && 15>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_DESL); + else if ((r&0xFF)==PT_PLNT && 5>(rand()%100)) + sim->create_part(r>>8, x+rx, y+ry, PT_WOOD); + else if ((r&0xFF)==PT_DESL && 15>(rand()%1000)) + sim->part_change_type(r>>8,x+rx,y+ry,PT_GAS); + else if ((r&0xFF)==PT_COAL && 5>(rand()%100)) + sim->create_part(r>>8, x+rx, y+ry, PT_WOOD); + else if ((r&0xFF)==PT_DUST && 5>(rand()%100)) + sim->part_change_type(r>>8, x+rx, y+ry, PT_FWRK); + else if ((r&0xFF)==PT_FWRK && 5>(rand()%100)) + parts[r>>8].ctype = PT_DUST; + else if ((r&0xFF)==PT_ACID && 5>(rand()%100)) + sim->create_part(r>>8, x+rx, y+ry, PT_ISOZ); + /*if(parts[r>>8].type>1 && parts[r>>8].type!=PT_NEUT && parts[r>>8].type-1!=PT_NEUT && parts[r>>8].type-1!=PT_STKM && + (ptypes[parts[r>>8].type-1].menusection==SC_LIQUID|| + ptypes[parts[r>>8].type-1].menusection==SC_EXPLOSIVE|| + ptypes[parts[r>>8].type-1].menusection==SC_GAS|| + ptypes[parts[r>>8].type-1].menusection==SC_POWDERS) && 15>(rand()%1000)) + parts[r>>8].type--;*/ + } + return 0; +} + +int graphics_NEUT(GRAPHICS_FUNC_ARGS) +{ + *firea = 120; + *firer = 10; + *fireg = 80; + *fireb = 120; + + *pixel_mode |= FIRE_ADD; + return 1; +} diff --git a/src/elements/newgraphics.cpp b/src/elements/newgraphics.cpp new file mode 100644 index 0000000..83da27b --- /dev/null +++ b/src/elements/newgraphics.cpp @@ -0,0 +1,541 @@ +#include "element.h" +#include "hmap.h" + +int graphics_QRTZ(GRAPHICS_FUNC_ARGS) //QRTZ and PQRT +{ + int t = cpart->type, z = cpart->tmp - 5;//speckles! + /*if (cpart->temp>(ptransitions[t].thv-800.0f))//hotglow for quartz + { + float frequency = 3.1415/(2*ptransitions[t].thv-(ptransitions[t].thv-800.0f)); + int q = (cpart->temp>ptransitions[t].thv)?ptransitions[t].thv-(ptransitions[t].thv-800.0f):cpart->temp-(ptransitions[t].thv-800.0f); + *colr += sin(frequency*q) * 226 + (z * 16); + *colg += sin(frequency*q*4.55 +3.14) * 34 + (z * 16); + *colb += sin(frequency*q*2.22 +3.14) * 64 + (z * 16); + } + else*/ + { + *colr += z * 16; + *colg += z * 16; + *colb += z * 16; + } + return 0; +} +int graphics_CLST(GRAPHICS_FUNC_ARGS) +{ + int z = cpart->tmp - 5;//speckles! + *colr += z * 16; + *colg += z * 16; + *colb += z * 16; + return 0; +} +int graphics_CBNW(GRAPHICS_FUNC_ARGS) +{ + int z = cpart->tmp2 - 20;//speckles! + *colr += z * 1; + *colg += z * 2; + *colb += z * 8; + return 0; +} +int graphics_SPNG(GRAPHICS_FUNC_ARGS) +{ + *colr -= cpart->life*15; + *colg -= cpart->life*15; + *colb -= cpart->life*15; + if (*colr<=50) + *colr = 50; + if (*colg<=50) + *colg = 50; + if (*colb<=20) + *colb = 20; + return 0; +} +int graphics_LIFE(GRAPHICS_FUNC_ARGS) +{ + pixel pc; + if (cpart->ctype==NGT_LOTE)//colors for life states + { + if (cpart->tmp==2) + pc = PIXRGB(255, 128, 0); + else if (cpart->tmp==1) + pc = PIXRGB(255, 255, 0); + else + pc = PIXRGB(255, 0, 0); + } + else if (cpart->ctype==NGT_FRG2)//colors for life states + { + if (cpart->tmp==2) + pc = PIXRGB(0, 100, 50); + else + pc = PIXRGB(0, 255, 90); + } + else if (cpart->ctype==NGT_STAR)//colors for life states + { + if (cpart->tmp==4) + pc = PIXRGB(0, 0, 128); + else if (cpart->tmp==3) + pc = PIXRGB(0, 0, 150); + else if (cpart->tmp==2) + pc = PIXRGB(0, 0, 190); + else if (cpart->tmp==1) + pc = PIXRGB(0, 0, 230); + else + pc = PIXRGB(0, 0, 70); + } + else if (cpart->ctype==NGT_FROG)//colors for life states + { + if (cpart->tmp==2) + pc = PIXRGB(0, 100, 0); + else + pc = PIXRGB(0, 255, 0); + } + else if (cpart->ctype==NGT_BRAN)//colors for life states + { + if (cpart->tmp==1) + pc = PIXRGB(150, 150, 0); + else + pc = PIXRGB(255, 255, 0); + } else { + //pc = gmenu[cpart->ctype].colour; + } + *colr = PIXR(pc); + *colg = PIXG(pc); + *colb = PIXB(pc); + return 0; +} +int graphics_DUST(GRAPHICS_FUNC_ARGS) +{ + if(cpart->life >= 1) + { + *colr = cpart->flags; + *colg = cpart->tmp; + *colb = cpart->ctype; + if (ren->decorations_enable && cpart->dcolour) + { + int a = (cpart->dcolour>>24)&0xFF; + *colr = (a*((cpart->dcolour>>16)&0xFF) + (255-a)**colr) >> 8; + *colg = (a*((cpart->dcolour>>8)&0xFF) + (255-a)**colg) >> 8; + *colb = (a*((cpart->dcolour)&0xFF) + (255-a)**colb) >> 8; + } + *pixel_mode |= PMODE_GLOW; + /**firea = 255; + *firer = *colr; + *fireg = *colg; + *fireb = *colb;*/ + } + return 0; +} +int graphics_GRAV(GRAPHICS_FUNC_ARGS) +{ + int GRAV_R, GRAV_B, GRAV_G, GRAV_R2, GRAV_B2, GRAV_G2; + *colr = 20; + *colg = 20; + *colb = 20; + if (cpart->vx>0) + { + *colr += (cpart->vx)*GRAV_R; + *colg += (cpart->vx)*GRAV_G; + *colb += (cpart->vx)*GRAV_B; + } + if (cpart->vy>0) + { + *colr += (cpart->vy)*GRAV_G; + *colg += (cpart->vy)*GRAV_B; + *colb += (cpart->vy)*GRAV_R; + + } + if (cpart->vx<0) + { + *colr -= (cpart->vx)*GRAV_B; + *colg -= (cpart->vx)*GRAV_R; + *colb -= (cpart->vx)*GRAV_G; + + } + if (cpart->vy<0) + { + *colr -= (cpart->vy)*GRAV_R2; + *colg -= (cpart->vy)*GRAV_G2; + *colb -= (cpart->vy)*GRAV_B2; + } + return 0; +} +int graphics_WIFI(GRAPHICS_FUNC_ARGS) +{ + float frequency = 0.0628; + int q = cpart->tmp; + *colr = sin(frequency*q + 0) * 127 + 128; + *colg = sin(frequency*q + 2) * 127 + 128; + *colb = sin(frequency*q + 4) * 127 + 128; + return 0; +} +int graphics_PRTI(GRAPHICS_FUNC_ARGS) +{ + *firea = 8; + *firer = 255; + *fireg = 0; + *fireb = 0; + *pixel_mode |= EFFECT_GRAVIN; + *pixel_mode &= ~PMODE; + *pixel_mode |= PMODE_ADD; + return 1; +} +int graphics_PRTO(GRAPHICS_FUNC_ARGS) +{ + *firea = 8; + *firer = 0; + *fireg = 0; + *fireb = 255; + *pixel_mode |= EFFECT_GRAVOUT; + *pixel_mode &= ~PMODE; + *pixel_mode |= PMODE_ADD; + return 1; +} +int graphics_BIZR(GRAPHICS_FUNC_ARGS) //BIZR, BIZRG, BIZRS +{ + int x = 0; + *colg = 0; + *colb = 0; + *colr = 0; + for (x=0; x<12; x++) { + *colr += (cpart->ctype >> (x+18)) & 1; + *colb += (cpart->ctype >> x) & 1; + } + for (x=0; x<12; x++) + *colg += (cpart->ctype >> (x+9)) & 1; + x = 624/(*colr+*colg+*colb+1); + *colr *= x; + *colg *= x; + *colb *= x; + if(fabs(cpart->vx)+fabs(cpart->vy)>0) + { + *firea = 255; + *fireg = *colg/5 * fabs(cpart->vx)+fabs(cpart->vy); + *fireb = *colb/5 * fabs(cpart->vx)+fabs(cpart->vy); + *firer = *colr/5 * fabs(cpart->vx)+fabs(cpart->vy); + *pixel_mode |= FIRE_ADD; + } + return 0; +} +int graphics_INVS(GRAPHICS_FUNC_ARGS) +{ + //pv[ny/CELL][nx/CELL]>4.0f || pv[ny/CELL][nx/CELL]<-4.0f + if(cpart->tmp) + { + *cola = 100; + *colr = 15; + *colg = 0; + *colb = 150; + *pixel_mode &= PMODE; + *pixel_mode |= PMODE_BLEND; + } + return 0; +} +int graphics_ACID(GRAPHICS_FUNC_ARGS) +{ + int s = cpart->life; + if (s>75) s = 75; //These two should not be here. + if (s<49) s = 49; + s = (s-49)*3; + if (s==0) s = 1; + *colr += s*4; + *colg += s*1; + *colb += s*2; + *pixel_mode |= PMODE_BLUR; + return 0; +} +int graphics_FILT(GRAPHICS_FUNC_ARGS) +{ + int x, temp_bin = (int)((cpart->temp-273.0f)*0.025f); + if (temp_bin < 0) temp_bin = 0; + if (temp_bin > 25) temp_bin = 25; + cpart->ctype = 0x1F << temp_bin; + *colg = 0; + *colb = 0; + *colr = 0; + for (x=0; x<12; x++) { + *colr += (cpart->ctype >> (x+18)) & 1; + *colb += (cpart->ctype >> x) & 1; + } + for (x=0; x<12; x++) + *colg += (cpart->ctype >> (x+9)) & 1; + x = 624/(*colr+*colg+*colb+1); + *cola = 127; + *colr *= x; + *colg *= x; + *colb *= x; + *pixel_mode &= ~PMODE; + *pixel_mode |= PMODE_BLEND; + return 0; +} +int graphics_BRAY(GRAPHICS_FUNC_ARGS) +{ + int x, trans = 255; + if(cpart->tmp==0) + { + trans = cpart->life * 7; + if (trans>255) trans = 255; + if (cpart->ctype) { + *colg = 0; + *colb = 0; + *colr = 0; + for (x=0; x<12; x++) { + *colr += (cpart->ctype >> (x+18)) & 1; + *colb += (cpart->ctype >> x) & 1; + } + for (x=0; x<12; x++) + *colg += (cpart->ctype >> (x+9)) & 1; + x = 624/(*colr+*colg+*colb+1); + *colr *= x; + *colg *= x; + *colb *= x; + } + } + else if(cpart->tmp==1) + { + trans = cpart->life/4; + if (trans>255) trans = 255; + if (cpart->ctype) { + *colg = 0; + *colb = 0; + *colr = 0; + for (x=0; x<12; x++) { + *colr += (cpart->ctype >> (x+18)) & 1; + *colb += (cpart->ctype >> x) & 1; + } + for (x=0; x<12; x++) + *colg += (cpart->ctype >> (x+9)) & 1; + x = 624/(*colr+*colg+*colb+1); + *colr *= x; + *colg *= x; + *colb *= x; + } + } + else if(cpart->tmp==2) + { + trans = cpart->life*100; + if (trans>255) trans = 255; + *colr = 255; + *colg = 150; + *colb = 50; + } + *cola = trans; + *pixel_mode &= ~PMODE; + *pixel_mode |= PMODE_BLEND; + return 0; +} +int graphics_SWCH(GRAPHICS_FUNC_ARGS) +{ + if(cpart->life >= 10) + { + *colr = 17; + *colg = 217; + *colb = 24; + *pixel_mode |= PMODE_GLOW; + } + return 0; +} +int graphics_THDR(GRAPHICS_FUNC_ARGS) +{ + *firea = 160; + *fireg = 192; + *fireb = 255; + *firer = 144; + *pixel_mode |= FIRE_ADD; + return 1; +} +int graphics_GLOW(GRAPHICS_FUNC_ARGS) +{ + *firer = restrict_flt(cpart->temp-(275.13f+32.0f), 0, 128)/50.0f; + *fireg = restrict_flt(cpart->ctype, 0, 128)/50.0f; + *fireb = restrict_flt(cpart->tmp, 0, 128)/50.0f; + + *colr = restrict_flt(64.0f+cpart->temp-(275.13f+32.0f), 0, 255); + *colg = restrict_flt(64.0f+cpart->ctype, 0, 255); + *colb = restrict_flt(64.0f+cpart->tmp, 0, 255); + + *pixel_mode |= FIRE_ADD; + return 0; +} +int graphics_LCRY(GRAPHICS_FUNC_ARGS) +{ + if(ren->decorations_enable && cpart->dcolour && cpart->dcolour&0xFF000000) + { + *colr = (cpart->dcolour>>16)&0xFF; + *colg = (cpart->dcolour>>8)&0xFF; + *colb = (cpart->dcolour)&0xFF; + + if(cpart->tmp2<10){ + *colr /= 10-cpart->tmp2; + *colg /= 10-cpart->tmp2; + *colb /= 10-cpart->tmp2; + } + + } + else + { + *colr = *colg = *colb = 0x50+((cpart->tmp2>10?10:cpart->tmp2)*10); + } + *pixel_mode |= NO_DECO; + return 0; + + /*int lifemod = ((cpart->tmp2>10?10:cpart->tmp2)*10); + *colr += lifemod; + *colg += lifemod; + *colb += lifemod; + if(decorations_enable && cpart->dcolour && cpart->dcolour&0xFF000000) + { + lifemod *= 2.5f; + if(lifemod < 40) + lifemod = 40; + *colr = (lifemod*((cpart->dcolour>>16)&0xFF) + (255-lifemod)**colr) >> 8; + *colg = (lifemod*((cpart->dcolour>>8)&0xFF) + (255-lifemod)**colg) >> 8; + *colb = (lifemod*((cpart->dcolour)&0xFF) + (255-lifemod)**colb) >> 8; + } + *pixel_mode |= NO_DECO; + return 0;*/ +} +int graphics_PCLN(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*10); + *colr += lifemod; + *colg += lifemod; + return 0; +} +int graphics_PBCN(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*10); + *colr += lifemod; + *colg += lifemod/2; + return 0; +} +int graphics_DLAY(GRAPHICS_FUNC_ARGS) +{ + int stage = (int)(((float)cpart->life/(cpart->temp-273.15))*100.0f); + *colr += stage; + *colg += stage; + *colb += stage; + return 0; +} +int graphics_HSWC(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*19); + *colr += lifemod; + return 0; +} +int graphics_PVOD(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*16); + *colr += lifemod; + return 0; +} +int graphics_STOR(GRAPHICS_FUNC_ARGS) +{ + if(cpart->tmp){ + *pixel_mode |= PMODE_GLOW; + *colr = 0x50; + *colg = 0xDF; + *colb = 0xDF; + } else { + *colr = 0x20; + *colg = 0xAF; + *colb = 0xAF; + } + return 0; +} +int graphics_PUMP(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*19); + *colb += lifemod; + return 0; +} +int graphics_GPMP(GRAPHICS_FUNC_ARGS) +{ + int lifemod = ((cpart->life>10?10:cpart->life)*19); + *colg += lifemod; + *colb += lifemod; + return 0; +} +int graphics_HFLM(GRAPHICS_FUNC_ARGS) +{ + int caddress = restrict_flt(restrict_flt((float)((int)(cpart->life/2)), 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); + *colr = (unsigned char)hflm_data[caddress]; + *colg = (unsigned char)hflm_data[caddress+1]; + *colb = (unsigned char)hflm_data[caddress+2]; + + *firea = 255; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode = PMODE_NONE; //Clear default, don't draw pixel + *pixel_mode |= FIRE_ADD; + //Returning 0 means dynamic, do not cache + return 0; +} +int graphics_FIRW(GRAPHICS_FUNC_ARGS) +{ + if(cpart->tmp>=3) + { + int caddress = restrict_flt(restrict_flt((float)(cpart->tmp-4), 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); + *colr = (unsigned char)firw_data[caddress]; + *colg = (unsigned char)firw_data[caddress+1]; + *colb = (unsigned char)firw_data[caddress+2]; + + if (ren->decorations_enable && cpart->dcolour) + { + int a = (cpart->dcolour>>24)&0xFF; + *colr = (a*((cpart->dcolour>>16)&0xFF) + (255-a)**colr) >> 8; + *colg = (a*((cpart->dcolour>>8)&0xFF) + (255-a)**colg) >> 8; + *colb = (a*((cpart->dcolour)&0xFF) + (255-a)**colb) >> 8; + } + + *firea = cpart->life*4; + if(*firea > 240) + *firea = 240; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode = PMODE_NONE; //Clear default, don't draw pixel + *pixel_mode |= FIRE_ADD; + //Returning 0 means dynamic, do not cache + } + else if(cpart->tmp > 0) + { + *pixel_mode |= PMODE_GLOW; + } + return 0; +} +int graphics_GBMB(GRAPHICS_FUNC_ARGS) +{ + if (cpart->life <= 0) { + *pixel_mode |= PMODE_FLARE; + } + else + { + *pixel_mode |= PMODE_SPARK; + } + return 0; +} +int graphics_COAL(GRAPHICS_FUNC_ARGS) //Both COAL and Broken Coal +{ + *colr += (cpart->tmp2-295.15f)/3; + + if (*colr > 170) + *colr = 170; + if (*colr < *colg) + *colr = *colg; + + *colg = *colb = *colr; + + if((cpart->temp-295.15f) > 300.0f-200.0f) + { + float frequency = 3.1415/(2*300.0f-(300.0f-200.0f)); + int q = ((cpart->temp-295.15f)>300.0f)?300.0f-(300.0f-200.0f):(cpart->temp-295.15f)-(300.0f-200.0f); + + *colr += sin(frequency*q) * 226; + *colg += sin(frequency*q*4.55 +3.14) * 34; + *colb += sin(frequency*q*2.22 +3.14) * 64; + } + return 0; +} + diff --git a/src/elements/none.cpp b/src/elements/none.cpp new file mode 100644 index 0000000..50f301f --- /dev/null +++ b/src/elements/none.cpp @@ -0,0 +1,6 @@ +#include "element.h" + +int update_(UPDATE_FUNC_ARGS) { + + return 0; +} diff --git a/src/elements/nptct.cpp b/src/elements/nptct.cpp new file mode 100644 index 0000000..2d68a9b --- /dev/null +++ b/src/elements/nptct.cpp @@ -0,0 +1,7 @@ +#include "element.h" + +int update_NPTCT(UPDATE_FUNC_ARGS) { + if (parts[i].temp>295.0f) + parts[i].temp -= 2.5f; + return 0; +} diff --git a/src/elements/nwhl.cpp b/src/elements/nwhl.cpp new file mode 100644 index 0000000..f53b657 --- /dev/null +++ b/src/elements/nwhl.cpp @@ -0,0 +1,6 @@ +#include "element.h" + +int update_NWHL(UPDATE_FUNC_ARGS) { + sim->gravmap[(y/CELL)*(XRES/CELL)+(x/CELL)] -= 0.1f; + return 0; +} diff --git a/src/elements/pbcn.cpp b/src/elements/pbcn.cpp new file mode 100644 index 0000000..7e99397 --- /dev/null +++ b/src/elements/pbcn.cpp @@ -0,0 +1,83 @@ +#include "element.h" + +int update_PBCN(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + if (!parts[i].tmp2 && sim->pv[y/CELL][x/CELL]>4.0f) + parts[i].tmp2 = rand()%40+80; + if (parts[i].tmp2) + { + float advection = 0.1f; + parts[i].vx += advection*sim->vx[y/CELL][x/CELL]; + parts[i].vy += advection*sim->vy[y/CELL][x/CELL]; + parts[i].tmp2--; + if(!parts[i].tmp2){ + sim->kill_part(i); + return 1; + } + } + if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || (parts[i].ctype==PT_LIFE && (parts[i].tmp<0 || parts[i].tmp>=NGOLALT))) + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_BCLN && (r&0xFF)!=PT_SPRK && + (r&0xFF)!=PT_NSCN && (r&0xFF)!=PT_PSCN && + (r&0xFF)!=PT_STKM && (r&0xFF)!=PT_STKM2 && + (r&0xFF)!=PT_PBCN && (r&0xFF)<PT_NUM) + { + parts[i].ctype = r&0xFF; + if ((r&0xFF)==PT_LIFE) + parts[i].tmp = parts[r>>8].ctype; + } + } + if (parts[i].life==10) + { + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_PBCN) + { + if (parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[r>>8].life==0) + parts[r>>8].life = 10; + } + } + } + if (parts[i].ctype>0 && parts[i].ctype<PT_NUM && parts[i].life==10) { + if (parts[i].ctype==PT_PHOT) {//create photons a different way + for (rx=-1; rx<2; rx++) { + for (ry=-1; ry<2; ry++) { + int r = sim->create_part(-1, x+rx, y+ry, parts[i].ctype); + if (r!=-1) { + parts[r].vx = rx*3; + parts[r].vy = ry*3; + } + } + } + } + else if (parts[i].ctype==PT_LIFE) {//create life a different way + for (rx=-1; rx<2; rx++) { + for (ry=-1; ry<2; ry++) { + sim->create_part(-1, x+rx, y+ry, parts[i].ctype|(parts[i].tmp<<8)); + } + } + } else { + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype); + } + } + return 0; +} diff --git a/src/elements/pcln.cpp b/src/elements/pcln.cpp new file mode 100644 index 0000000..cd1ed4f --- /dev/null +++ b/src/elements/pcln.cpp @@ -0,0 +1,73 @@ +#include "element.h" + +int update_PCLN(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK) + { + if (parts[r>>8].ctype==PT_PSCN) + parts[i].life = 10; + else if (parts[r>>8].ctype==PT_NSCN) + parts[i].life = 9; + } + if ((r&0xFF)==PT_PCLN) + { + if (parts[i].life==10&&parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[i].life==0&&parts[r>>8].life==10) + parts[i].life = 10; + } + } + if (parts[i].ctype<=0 || parts[i].ctype>=PT_NUM || (parts[i].ctype==PT_LIFE && (parts[i].tmp<0 || parts[i].tmp>=NGOLALT))) + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->photons[y+ry][x+rx]; + if (!r) + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_CLNE && (r&0xFF)!=PT_PCLN && + (r&0xFF)!=PT_BCLN && (r&0xFF)!=PT_SPRK && + (r&0xFF)!=PT_NSCN && (r&0xFF)!=PT_PSCN && + (r&0xFF)!=PT_STKM && (r&0xFF)!=PT_STKM2 && + (r&0xFF)!=PT_PBCN && (r&0xFF)<PT_NUM) + { + parts[i].ctype = r&0xFF; + if ((r&0xFF)==PT_LIFE) + parts[i].tmp = parts[r>>8].ctype; + } + } + if (parts[i].ctype>0 && parts[i].ctype<PT_NUM && parts[i].life==10) { + if (parts[i].ctype==PT_PHOT) {//create photons a different way + for (rx=-1; rx<2; rx++) { + for (ry=-1; ry<2; ry++) { + int r = sim->create_part(-1, x+rx, y+ry, parts[i].ctype); + if (r!=-1) { + parts[r].vx = rx*3; + parts[r].vy = ry*3; + } + } + } + } + else if (parts[i].ctype==PT_LIFE) {//create life a different way + for (rx=-1; rx<2; rx++) { + for (ry=-1; ry<2; ry++) { + sim->create_part(-1, x+rx, y+ry, parts[i].ctype|(parts[i].tmp<<8)); + } + } + } else { + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, parts[i].ctype); + } + } + return 0; +} diff --git a/src/elements/phot.cpp b/src/elements/phot.cpp new file mode 100644 index 0000000..3ed6b5d --- /dev/null +++ b/src/elements/phot.cpp @@ -0,0 +1,84 @@ +#include "element.h" + +int update_PHOT(UPDATE_FUNC_ARGS) { + int r, rt, rx, ry; + float rr, rrr; + parts[i].pavg[0] = x; + parts[i].pavg[1] = y; + if (!parts[i].ctype) { + sim->kill_part(i); + return 1; + } + if (1>rand()%10) update_PYRO(UPDATE_FUNC_SUBCALL_ARGS); + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES && (rx || ry)) { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_ISOZ && 5>(rand()%2000)) + { + parts[i].vx *= 0.90; + parts[i].vy *= 0.90; + sim->create_part(r>>8, x+rx, y+ry, PT_PHOT); + rrr = (rand()%360)*3.14159f/180.0f; + rr = (rand()%128+128)/127.0f; + parts[r>>8].vx = rr*cosf(rrr); + parts[r>>8].vy = rr*sinf(rrr); + sim->pv[y/CELL][x/CELL] -= 15.0f * CFDS; + } + if ((r&0xFF)==PT_ISZS && 5>(rand()%2000)) + { + parts[i].vx *= 0.90; + parts[i].vy *= 0.90; + sim->create_part(r>>8, x+rx, y+ry, PT_PHOT); + rr = (rand()%228+128)/127.0f; + rrr = (rand()%360)*3.14159f/180.0f; + parts[r>>8].vx = rr*cosf(rrr); + parts[r>>8].vy = rr*sinf(rrr); + sim->pv[y/CELL][x/CELL] -= 15.0f * CFDS; + } + } + r = pmap[y][x]; + if((r&0xFF) == PT_QRTZ && r)// && parts[i].ctype==0x3FFFFFFF) + { + float a = (rand()%360)*3.14159f/180.0f; + parts[i].vx = 3.0f*cosf(a); + parts[i].vy = 3.0f*sinf(a); + if(parts[i].ctype == 0x3FFFFFFF) + parts[i].ctype = 0x1F<<(rand()%26); + parts[i].life++; //Delay death + } + //r = pmap[y][x]; + //rt = r&0xFF; + /*if (rt==PT_CLNE || rt==PT_PCLN || rt==PT_BCLN || rt==PT_PBCN) { + if (!parts[r>>8].ctype) + parts[r>>8].ctype = PT_PHOT; + }*/ + + return 0; +} + +int graphics_PHOT(GRAPHICS_FUNC_ARGS) +{ + int x = 0; + *colr = *colg = *colb = 0; + for (x=0; x<12; x++) { + *colr += (cpart->ctype >> (x+18)) & 1; + *colb += (cpart->ctype >> x) & 1; + } + for (x=0; x<12; x++) + *colg += (cpart->ctype >> (x+9)) & 1; + x = 624/(*colr+*colg+*colb+1); + *colr *= x; + *colg *= x; + *colb *= x; + + *firea = 100; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode |= FIRE_ADD; + return 0; +} diff --git a/src/elements/pipe.cpp b/src/elements/pipe.cpp new file mode 100644 index 0000000..08432f5 --- /dev/null +++ b/src/elements/pipe.cpp @@ -0,0 +1,332 @@ +#include "element.h" + +signed char pos_1_rx[] = {-1,-1,-1, 0, 0, 1, 1, 1}; +signed char pos_1_ry[] = {-1, 0, 1,-1, 1,-1, 0, 1}; + +void pushParticle(Simulation * sim, int i, int count, int original) +{ + int rndstore, rnd, rx, ry, r, x, y, np, q, notctype=(((sim->parts[i].ctype)%3)+2); + if ((sim->parts[i].tmp&0xFF) == 0 || count >= 2)//don't push if there is nothing there, max speed of 2 per frame + return; + x = (int)(sim->parts[i].x+0.5f); + y = (int)(sim->parts[i].y+0.5f); + if( !(sim->parts[i].tmp&0x200) ) + { + //normal random push + rndstore = rand(); + // RAND_MAX is at least 32767 on all platforms i.e. pow(8,5)-1 + // so can go 5 cycles without regenerating rndstore + for (q=0; q<3; q++)//try to push twice + { + rnd = rndstore&7; + rndstore = rndstore>>3; + rx = pos_1_rx[rnd]; + ry = pos_1_ry[rnd]; + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = sim->pmap[y+ry][x+rx]; + if (!r) + continue; + else if ((r&0xFF)==PT_PIPE && sim->parts[r>>8].ctype!=notctype && (sim->parts[r>>8].tmp&0xFF)==0) + { + sim->parts[r>>8].tmp = (sim->parts[r>>8].tmp&~0xFF) | (sim->parts[i].tmp&0xFF); + sim->parts[r>>8].temp = sim->parts[i].temp; + sim->parts[r>>8].flags = sim->parts[i].flags; + sim->parts[r>>8].pavg[0] = sim->parts[i].pavg[0]; + sim->parts[r>>8].pavg[1] = sim->parts[i].pavg[1]; + if (r>>8 > original) + sim->parts[r>>8].tmp2 = 1;//skip particle push, normalizes speed + sim->parts[i].tmp &= ~0xFF; + count++; + pushParticle(sim, r>>8,count,original); + } + } + } + } + else //predefined 1 pixel thick pipe movement + { + int coords = 7 - ((sim->parts[i].tmp>>10)&7); + r = sim->pmap[y+ pos_1_ry[coords]][x+ pos_1_rx[coords]]; + if (!r) + { + } + else if ((r&0xFF)==PT_PIPE && sim->parts[r>>8].ctype!=notctype && (sim->parts[r>>8].tmp&0xFF)==0) + { + sim->parts[r>>8].tmp = (sim->parts[r>>8].tmp&~0xFF) | (sim->parts[i].tmp&0xFF); + sim->parts[r>>8].temp = sim->parts[i].temp; + sim->parts[r>>8].flags = sim->parts[i].flags; + sim->parts[r>>8].pavg[0] = sim->parts[i].pavg[0]; + sim->parts[r>>8].pavg[1] = sim->parts[i].pavg[1]; + if (r>>8 > original) + sim->parts[r>>8].tmp2 = 1;//skip particle push, normalizes speed + sim->parts[i].tmp &= ~0xFF; + count++; + pushParticle(sim, r>>8,count,original); + } + + + } + return; +} + +int update_PIPE(UPDATE_FUNC_ARGS) { + int r, rx, ry, np; + int rnd, rndstore; + if (parts[i].ctype>=2 && parts[i].ctype<=4) + { + if (parts[i].life==3) + { + int lastneighbor = -1; + int neighborcount = 0; + int count = 0; + // make automatic pipe pattern + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_PIPE&&parts[r>>8].ctype==1) + { + parts[r>>8].ctype = (((parts[i].ctype)%3)+2);//reverse + parts[r>>8].life = 6; + if ( parts[i].tmp&0x100)//is a single pixel pipe + { + parts[r>>8].tmp |= 0x200;//will transfer to a single pixel pipe + parts[r>>8].tmp |= count<<10;//coords of where it came from + } + neighborcount ++; + lastneighbor = r>>8; + } + else if ((r&0xFF)==PT_PIPE&&parts[r>>8].ctype!=(((parts[i].ctype-1)%3)+2)) + { + neighborcount ++; + lastneighbor = r>>8; + } + count++; + } + if(neighborcount == 1) + parts[lastneighbor].tmp |= 0x100; + } + else + { + if (parts[i].tmp2 == 1)//skip particle push to prevent particle number being higher causeing speed up + { + parts[i].tmp2 = 0 ; + } + else + { + pushParticle(sim, i,0,i); + } + + if (nt)//there is something besides PIPE around current particle + { + rndstore = rand(); + rnd = rndstore&7; + rndstore = rndstore>>3; + rx = pos_1_rx[rnd]; + ry = pos_1_ry[rnd]; + if (x+rx>=0 && y+ry>=0 && x+rx<XRES && y+ry<YRES) + { + r = pmap[y+ry][x+rx]; + if(!r) + r = sim->photons[y+ry][x+rx]; + if (surround_space && !r && (parts[i].tmp&0xFF)!=0) //creating at end + { + np = sim->create_part(-1,x+rx,y+ry,parts[i].tmp&0xFF); + if (np!=-1) + { + parts[np].temp = parts[i].temp;//pipe saves temp and life now + parts[np].life = parts[i].flags; + parts[np].tmp = parts[i].pavg[0]; + parts[np].ctype = parts[i].pavg[1]; + parts[i].tmp &= ~0xFF; + } + } + //try eating particle at entrance + else if ((parts[i].tmp&0xFF) == 0 && (sim->ptypes[r&0xFF].falldown!= 0 || sim->ptypes[r&0xFF].state == ST_GAS)) + { + if ((r&0xFF)==PT_SOAP) + sim->detach(r>>8); + parts[i].tmp = (parts[i].tmp&~0xFF) | parts[r>>8].type; + parts[i].temp = parts[r>>8].temp; + parts[i].flags = parts[r>>8].life; + parts[i].pavg[0] = parts[r>>8].tmp; + parts[i].pavg[1] = parts[r>>8].ctype; + sim->kill_part(r>>8); + } + else if ((parts[i].tmp&0xFF) == 0 && (r&0xFF)==PT_STOR && parts[r>>8].tmp && (sim->ptypes[parts[r>>8].tmp].falldown!= 0 || sim->ptypes[parts[r>>8].tmp].state == ST_GAS)) + { + parts[i].tmp = parts[r>>8].tmp; + parts[i].temp = parts[r>>8].temp; + parts[i].flags = parts[r>>8].flags; + parts[i].pavg[0] = parts[r>>8].pavg[0]; + parts[i].pavg[1] = parts[r>>8].pavg[1]; + parts[r>>8].tmp = 0; + parts[r>>8].life = 0; + } + } + } + } + } + else if (!parts[i].ctype && parts[i].life<=10) + { + if (parts[i].temp<272.15)//manual pipe colors + { + if (parts[i].temp>173.25&&parts[i].temp<273.15) + { + parts[i].ctype = 2; + parts[i].life = 0; + } + if (parts[i].temp>73.25&&parts[i].temp<=173.15) + { + parts[i].ctype = 3; + parts[i].life = 0; + } + if (parts[i].temp>=0&&parts[i].temp<=73.15) + { + parts[i].ctype = 4; + parts[i].life = 0; + } + } + else + { + // make a border + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + { + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + sim->create_part(-1,x+rx,y+ry,PT_BRCK);//BRCK border, people didn't like DMND + } + } + if (parts[i].life<=1) + parts[i].ctype = 1; + } + } + else if (parts[i].ctype==1)//wait for empty space before starting to generate automatic pipe pattern + { + if (!parts[i].life) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + if (!pmap[y+ry][x+rx]) + parts[i].life=50; + } + } + else if (parts[i].life==5)//check for beginning of pipe single pixel + { + int issingle = 1; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((r&0xFF)==PT_PIPE && parts[i].ctype==1 && parts[i].life ) + issingle = 0; + } + if (issingle) + parts[i].tmp |= 0x100; + } + else if (parts[i].life==2) + { + parts[i].ctype = 2; + parts[i].life = 6; + } + } + return 0; +} + +int graphics_PIPE(GRAPHICS_FUNC_ARGS) +{ + + if ((cpart->tmp&0xFF)>0 && (cpart->tmp&0xFF)<PT_NUM) + { + //Create a temp. particle and do a subcall. + Particle tpart; + int t; + memset(&tpart, 0, sizeof(Particle)); + tpart.type = cpart->tmp&0xFF; + tpart.temp = cpart->temp; + tpart.life = cpart->flags; + tpart.tmp = cpart->pavg[0]; + tpart.ctype = cpart->pavg[1]; + t = tpart.type; + if (ren->graphicscache[t].isready) + { + *pixel_mode = ren->graphicscache[t].pixel_mode; + *colr = ren->graphicscache[t].colr; + *colg = ren->graphicscache[t].colg; + *colb = ren->graphicscache[t].colb; + *firea = ren->graphicscache[t].firea; + *firer = ren->graphicscache[t].firer; + *fireg = ren->graphicscache[t].fireg; + *fireb = ren->graphicscache[t].fireb; + } + else + { + *colr = PIXR(ren->sim->ptypes[t].pcolors); + *colg = PIXR(ren->sim->ptypes[t].pcolors); + *colb = PIXR(ren->sim->ptypes[t].pcolors); + if (ren->sim->ptypes[t].graphics_func) + { + (*(ren->sim->ptypes[t].graphics_func))(ren, &tpart, nx, ny, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, fireb); + } + else + { + graphics_DEFAULT(ren, &tpart, nx, ny, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, fireb); + } + } + //*colr = PIXR(ptypes[cpart->tmp&0xFF].pcolors); + //*colg = PIXG(ptypes[cpart->tmp&0xFF].pcolors); + //*colb = PIXB(ptypes[cpart->tmp&0xFF].pcolors); + } + else + { + if (cpart->ctype==2) + { + *colr = 50; + *colg = 1; + *colb = 1; + } + else if (cpart->ctype==3) + { + *colr = 1; + *colg = 50; + *colb = 1; + } + else if (cpart->ctype==4) + { + *colr = 1; + *colg = 1; + *colb = 50; + } + else if (cpart->temp<272.15&&cpart->ctype!=1) + { + if (cpart->temp>173.25&&cpart->temp<273.15) + { + *colr = 50; + *colg = 1; + *colb = 1; + } + if (cpart->temp>73.25&&cpart->temp<=173.15) + { + *colr = 1; + *colg = 50; + *colb = 1; + } + if (cpart->temp>=0&&cpart->temp<=73.15) + { + *colr = 1; + *colg = 1; + *colb = 50; + } + } + } + return 0; +} diff --git a/src/elements/plnt.cpp b/src/elements/plnt.cpp new file mode 100644 index 0000000..a44c8c2 --- /dev/null +++ b/src/elements/plnt.cpp @@ -0,0 +1,55 @@ +#include "element.h" + +int update_PLNT(UPDATE_FUNC_ARGS) { + int r, rx, ry, np; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR && 1>(rand()%250)) + { + np = sim->create_part(r>>8,x+rx,y+ry,PT_PLNT); + if (np<0) continue; + parts[np].life = 0; + } + else if ((r&0xFF)==PT_LAVA && 1>(rand()%250)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + else if (((r&0xFF)==PT_SMKE || (r&0xFF)==PT_CO2) && (1>rand()%250)) + { + sim->kill_part(r>>8); + parts[i].life = rand()%60 + 60; + } + else if ((r&0xFF)==PT_WOOD && (1>rand()%20) && abs(rx+ry)<=2 && sim->VINE_MODE) + { + int nnx = rand()%3 -1; + int nny = rand()%3 -1; + if (x+rx+nnx>=0 && y+ry+nny>0 && x+rx+nnx<XRES && y+ry+nny<YRES && (nnx || nny)) + { + if (pmap[y+ry+nny][x+rx+nnx]) + continue; + np = sim->create_part(-1,x+rx+nnx,y+ry+nny,PT_VINE); + if (np<0) continue; + parts[np].temp = parts[i].temp; + } + } + } + if (parts[i].life==2) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + sim->create_part(-1,x+rx,y+ry,PT_O2); + } + parts[i].life = 0; + } + return 0; +} diff --git a/src/elements/plsm.cpp b/src/elements/plsm.cpp new file mode 100644 index 0000000..c6f7c20 --- /dev/null +++ b/src/elements/plsm.cpp @@ -0,0 +1,20 @@ +#include "element.h" +#include "hmap.h" + +int graphics_PLSM(GRAPHICS_FUNC_ARGS) +{ + int caddress = restrict_flt(restrict_flt((float)cpart->life, 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); + *colr = (unsigned char)ren->plasma_data[caddress]; + *colg = (unsigned char)ren->plasma_data[caddress+1]; + *colb = (unsigned char)ren->plasma_data[caddress+2]; + + *firea = 255; + *firer = *colr; + *fireg = *colg; + *fireb = *colb; + + *pixel_mode = PMODE_GLOW | PMODE_ADD; //Clear default, don't draw pixel + *pixel_mode |= FIRE_ADD; + //Returning 0 means dynamic, do not cache + return 0; +} diff --git a/src/elements/plut.cpp b/src/elements/plut.cpp new file mode 100644 index 0000000..3e2820d --- /dev/null +++ b/src/elements/plut.cpp @@ -0,0 +1,9 @@ +#include "element.h" + +int update_PLUT(UPDATE_FUNC_ARGS) { + if (1>rand()%100 && ((int)(5.0f*sim->pv[y/CELL][x/CELL]))>(rand()%1000)) + { + sim->create_part(i, x, y, PT_NEUT); + } + return 0; +} diff --git a/src/elements/prti.cpp b/src/elements/prti.cpp new file mode 100644 index 0000000..df212d4 --- /dev/null +++ b/src/elements/prti.cpp @@ -0,0 +1,79 @@ +#include "element.h" +/*these are the count values of where the particle gets stored, depending on where it came from + 0 1 2 + 7 . 3 + 6 5 4 + PRTO does (count+4)%8, so that it will come out at the opposite place to where it came in + PRTO does +/-1 to the count, so it doesn't jam as easily +*/ +int portal_rx[8] = {-1, 0, 1, 1, 1, 0,-1,-1}; +int portal_ry[8] = {-1,-1,-1, 0, 1, 1, 1, 0}; + +int update_PRTI(UPDATE_FUNC_ARGS) { + int r, nnx, rx, ry, fe = 0; + int count =0; + parts[i].tmp = (int)((parts[i].temp-73.15f)/100+1); + if (parts[i].tmp>=CHANNELS) parts[i].tmp = CHANNELS-1; + else if (parts[i].tmp<0) parts[i].tmp = 0; + for (count=0; count<8; count++) + { + rx = portal_rx[count]; + ry = portal_ry[count]; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + fe = 1; + if (!r || (r&0xFF)==PT_PRTI || (r&0xFF)==PT_PRTO || (sim->ptypes[r&0xFF].falldown== 0 && sim->ptypes[r&0xFF].state != ST_GAS && (r&0xFF)!=PT_SPRK)) + { + r = sim->photons[y+ry][x+rx]; + if (!r || (r&0xFF)==PT_PRTI || (r&0xFF)==PT_PRTO || (sim->ptypes[r&0xFF].falldown== 0 && sim->ptypes[r&0xFF].state != ST_GAS && (r&0xFF)!=PT_SPRK)) + continue; + } + + if ((r&0xFF) == PT_SOAP) + sim->detach(r>>8); + + for ( nnx=0; nnx<80; nnx++) + if (!sim->portalp[parts[i].tmp][count][nnx].type) + { + sim->portalp[parts[i].tmp][count][nnx] = parts[r>>8]; + if ((r&0xFF)==PT_SPRK) + sim->part_change_type(r>>8,x+rx,y+ry,parts[r>>8].ctype); + else + sim->kill_part(r>>8); + fe = 1; + break; + } + } + } + + + if (fe) { + int orbd[4] = {0, 0, 0, 0}; //Orbital distances + int orbl[4] = {0, 0, 0, 0}; //Orbital locations + if (!parts[i].life) parts[i].life = rand(); + if (!parts[i].ctype) parts[i].ctype = rand(); + sim->orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl); + for (r = 0; r < 4; r++) { + if (orbd[r]>1) { + orbd[r] -= 12; + if (orbd[r]<1) { + orbd[r] = (rand()%128)+128; + orbl[r] = rand()%255; + } else { + orbl[r] += 2; + orbl[r] = orbl[r]%255; + } + } else { + orbd[r] = (rand()%128)+128; + orbl[r] = rand()%255; + } + } + sim->orbitalparts_set(&parts[i].life, &parts[i].ctype, orbd, orbl); + } else { + parts[i].life = 0; + parts[i].ctype = 0; + } + return 0; +} diff --git a/src/elements/prto.cpp b/src/elements/prto.cpp new file mode 100644 index 0000000..ee61abf --- /dev/null +++ b/src/elements/prto.cpp @@ -0,0 +1,88 @@ +#include "element.h" +/*these are the count values of where the particle gets stored, depending on where it came from + 0 1 2 + 7 . 3 + 6 5 4 + PRTO does (count+4)%8, so that it will come out at the opposite place to where it came in + PRTO does +/-1 to the count, so it doesn't jam as easily +*/ +int update_PRTO(UPDATE_FUNC_ARGS) { + int r, nnx, rx, ry, np, fe = 0; + int count = 0; + parts[i].tmp = (int)((parts[i].temp-73.15f)/100+1); + if (parts[i].tmp>=CHANNELS) parts[i].tmp = CHANNELS-1; + else if (parts[i].tmp<0) parts[i].tmp = 0; + for (count=0; count<8; count++) + { + rx = sim->portal_rx[count]; + ry = sim->portal_ry[count]; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + fe = 1; + if (r) + continue; + if (!r) + { + for ( nnx =0 ; nnx<80; nnx++) + { + int randomness = (count + rand()%3-1 + 4)%8;//add -1,0,or 1 to count + if (sim->portalp[parts[i].tmp][randomness][nnx].type==PT_SPRK)// TODO: make it look better, spark creation + { + sim->create_part(-1,x+1,y,PT_SPRK); + sim->create_part(-1,x+1,y+1,PT_SPRK); + sim->create_part(-1,x+1,y-1,PT_SPRK); + sim->create_part(-1,x,y-1,PT_SPRK); + sim->create_part(-1,x,y+1,PT_SPRK); + sim->create_part(-1,x-1,y+1,PT_SPRK); + sim->create_part(-1,x-1,y,PT_SPRK); + sim->create_part(-1,x-1,y-1,PT_SPRK); + sim->portalp[parts[i].tmp][randomness][nnx] = sim->emptyparticle; + break; + } + else if (sim->portalp[parts[i].tmp][randomness][nnx].type) + { + if (sim->portalp[parts[i].tmp][randomness][nnx].type==PT_STKM) + sim->player.spwn = 0; + if (sim->portalp[parts[i].tmp][randomness][nnx].type==PT_STKM2) + sim->player2.spwn = 0; + np = sim->create_part(-1, x+rx, y+ry, sim->portalp[parts[i].tmp][randomness][nnx].type); + if (np<0) continue; + parts[np] = sim->portalp[parts[i].tmp][randomness][nnx]; + parts[np].x = x+rx; + parts[np].y = y+ry; + sim->portalp[parts[i].tmp][randomness][nnx] = sim->emptyparticle; + break; + } + } + } + } + } + if (fe) { + int orbd[4] = {0, 0, 0, 0}; //Orbital distances + int orbl[4] = {0, 0, 0, 0}; //Orbital locations + if (!parts[i].life) parts[i].life = rand(); + if (!parts[i].ctype) parts[i].life = rand(); + sim->orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl); + for (r = 0; r < 4; r++) { + if (orbd[r]<254) { + orbd[r] += 16; + if (orbd[r]>254) { + orbd[r] = 0; + orbl[r] = rand()%255; + } + //orbl[r] += 1; + //orbl[r] = orbl[r]%255; + } else { + orbd[r] = 0; + orbl[r] = rand()%255; + } + } + sim->orbitalparts_set(&parts[i].life, &parts[i].ctype, orbd, orbl); + } else { + parts[i].life = 0; + parts[i].ctype = 0; + } + return 0; +} diff --git a/src/elements/pump.cpp b/src/elements/pump.cpp new file mode 100644 index 0000000..8a7254e --- /dev/null +++ b/src/elements/pump.cpp @@ -0,0 +1,41 @@ +#include "element.h" + +int update_PUMP(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + if (parts[i].life==10) + { + if (parts[i].temp>=256.0+273.15) + parts[i].temp=256.0+273.15; + if (parts[i].temp<= -256.0+273.15) + parts[i].temp = -256.0+273.15; + + if (sim->pv[y/CELL][x/CELL]<(parts[i].temp-273.15)) + sim->pv[y/CELL][x/CELL] += 0.1f*((parts[i].temp-273.15)-sim->pv[y/CELL][x/CELL]); + if (y+CELL<YRES && sim->pv[y/CELL+1][x/CELL]<(parts[i].temp-273.15)) + sim->pv[y/CELL+1][x/CELL] += 0.1f*((parts[i].temp-273.15)-sim->pv[y/CELL+1][x/CELL]); + if (x+CELL<XRES) + { + sim->pv[y/CELL][x/CELL+1] += 0.1f*((parts[i].temp-273.15)-sim->pv[y/CELL][x/CELL+1]); + if (y+CELL<YRES) + sim->pv[y/CELL+1][x/CELL+1] += 0.1f*((parts[i].temp-273.15)-sim->pv[y/CELL+1][x/CELL+1]); + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_PUMP) + { + if (parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[r>>8].life==0) + parts[r>>8].life = 10; + } + } + } + return 0; +} diff --git a/src/elements/pvod.cpp b/src/elements/pvod.cpp new file mode 100644 index 0000000..e645d0a --- /dev/null +++ b/src/elements/pvod.cpp @@ -0,0 +1,30 @@ +#include "element.h" + +int update_PVOD(UPDATE_FUNC_ARGS) { + int r, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK) + { + if (parts[r>>8].ctype==PT_PSCN) + parts[i].life = 10; + else if (parts[r>>8].ctype==PT_NSCN) + parts[i].life = 9; + } + if ((r&0xFF)==PT_PVOD) + { + if (parts[i].life==10&&parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[i].life==0&&parts[r>>8].life==10) + parts[i].life = 10; + } + } + return 0; +} diff --git a/src/elements/pyro.cpp b/src/elements/pyro.cpp new file mode 100644 index 0000000..790e295 --- /dev/null +++ b/src/elements/pyro.cpp @@ -0,0 +1,129 @@ +#include "element.h" + +int update_PYRO(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, t = parts[i].type; + if (t==PT_PLSM&&parts[i].ctype == PT_NBLE&&parts[i].life <=1) + { + t = PT_NBLE; + sim->part_change_type(i,x,y,t); + parts[i].life = 0; + } + if(t==PT_FIRE && parts[i].life <=1) + { + if (parts[i].tmp==3){ + t = PT_DSTW; + sim->part_change_type(i,x,y,t); + parts[i].life = 0; + parts[i].ctype = PT_FIRE; + } + else if (parts[i].temp<625) + { + t = PT_SMKE; + sim->part_change_type(i,x,y,t); + parts[i].life = rand()%20+250; + } + } + if(t==PT_PLSM && parts[i].life <=1) + { + if (parts[i].tmp==3){ + t = PT_DSTW; + sim->part_change_type(i,x,y,t); + parts[i].life = 0; + parts[i].ctype = PT_FIRE; + } + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->bmap[(y+ry)/CELL][(x+rx)/CELL] && sim->bmap[(y+ry)/CELL][(x+rx)/CELL]!=WL_STREAM) + continue; + rt = parts[r>>8].type; + if ((surround_space || sim->ptypes[rt].explosive) && + (t!=PT_SPRK || (rt!=PT_RBDM && rt!=PT_LRBD && rt!=PT_INSL)) && + (t!=PT_PHOT || rt!=PT_INSL) && + (rt!=PT_SPNG || parts[r>>8].life==0) && + sim->ptypes[rt].flammable && (sim->ptypes[rt].flammable + (int)(sim->pv[(y+ry)/CELL][(x+rx)/CELL]*10.0f))>(rand()%1000)) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_FIRE); + parts[r>>8].temp = restrict_flt(sim->ptypes[PT_FIRE].heat + (sim->ptypes[rt].flammable/2), MIN_TEMP, MAX_TEMP); + parts[r>>8].life = rand()%80+180; + parts[r>>8].tmp = parts[r>>8].ctype = 0; + if (sim->ptypes[rt].explosive) + sim->pv[y/CELL][x/CELL] += 0.25f * CFDS; + } + } + if (sim->legacy_enable) update_legacy_PYRO(UPDATE_FUNC_SUBCALL_ARGS); + return 0; +} + +int update_legacy_PYRO(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, lpv, t = parts[i].type; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->bmap[(y+ry)/CELL][(x+rx)/CELL] && sim->bmap[(y+ry)/CELL][(x+rx)/CELL]!=WL_STREAM) + continue; + rt = r&0xFF; + lpv = (int)sim->pv[(y+ry)/CELL][(x+rx)/CELL]; + if (lpv < 1) lpv = 1; + if (t!=PT_SPRK && sim->ptypes[rt].meltable && ((rt!=PT_RBDM && rt!=PT_LRBD) || t!=PT_SPRK) && ((t!=PT_FIRE&&t!=PT_PLSM) || (rt!=PT_METL && rt!=PT_IRON && rt!=PT_ETRD && rt!=PT_PSCN && rt!=PT_NSCN && rt!=PT_NTCT && rt!=PT_PTCT && rt!=PT_BMTL && rt!=PT_BRMT && rt!=PT_SALT && rt!=PT_INWR)) && + sim->ptypes[rt].meltable*lpv>(rand()%1000)) + { + if (t!=PT_LAVA || parts[i].life>0) + { + parts[r>>8].ctype = (rt==PT_BRMT)?PT_BMTL:parts[r>>8].type; + parts[r>>8].ctype = (parts[r>>8].ctype==PT_SAND)?PT_GLAS:parts[r>>8].ctype; + sim->part_change_type(r>>8,x+rx,y+ry,PT_LAVA); + parts[r>>8].life = rand()%120+240; + } + else + { + parts[i].life = 0; + t = parts[i].type = (parts[i].ctype)?parts[i].ctype:PT_STNE; + parts[i].ctype = PT_NONE;//rt; + sim->part_change_type(i,x,y,t); + return 1; + } + } + if (t!=PT_SPRK && (rt==PT_ICEI || rt==PT_SNOW)) + { + parts[r>>8].type = PT_WATR; + if (t==PT_FIRE) + { + sim->kill_part(i); + return 1; + } + if (t==PT_LAVA) + { + parts[i].life = 0; + t = parts[i].type = PT_STNE; + sim->part_change_type(i,x,y,t); + } + } + if (t!=PT_SPRK && (rt==PT_WATR || rt==PT_DSTW || rt==PT_SLTW)) + { + sim->kill_part(r>>8); + if (t==PT_FIRE) + { + sim->kill_part(i); + return 1; + } + if (t==PT_LAVA) + { + parts[i].life = 0; + t = parts[i].type = (parts[i].ctype)?parts[i].ctype:PT_STNE; + parts[i].ctype = PT_NONE; + sim->part_change_type(i,x,y,t); + } + } + } + return 0; +} diff --git a/src/elements/qrtz.cpp b/src/elements/qrtz.cpp new file mode 100644 index 0000000..7768765 --- /dev/null +++ b/src/elements/qrtz.cpp @@ -0,0 +1,94 @@ +#include "element.h" + +int update_QRTZ(UPDATE_FUNC_ARGS) { + int r, tmp, trade, rx, ry, np, t; + t = parts[i].type; + if (t == PT_QRTZ) + { + parts[i].pavg[0] = parts[i].pavg[1]; + parts[i].pavg[1] = sim->pv[y/CELL][x/CELL]; + if (parts[i].pavg[1]-parts[i].pavg[0] > 0.05*(parts[i].temp/3) || parts[i].pavg[1]-parts[i].pavg[0] < -0.05*(parts[i].temp/3)) + { + sim->part_change_type(i,x,y,PT_PQRT); + } + } + // absorb SLTW + if (parts[i].ctype!=-1) + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + else if ((r&0xFF)==PT_SLTW && (1>rand()%2500)) + { + sim->kill_part(r>>8); + parts[i].ctype ++; + } + } + // grow if absorbed SLTW + if (parts[i].ctype>0) + { + for ( trade = 0; trade<5; trade ++) + { + rx = rand()%3-1; + ry = rand()%3-1; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r && parts[i].ctype!=0) + { + np = sim->create_part(-1,x+rx,y+ry,PT_QRTZ); + if (np>-1) + { + parts[np].tmp = parts[i].tmp; + parts[i].ctype--; + if (5>rand()%10) + { + parts[np].ctype=-1;//dead qrtz + } + else if (!parts[i].ctype && 1>rand()%15) + { + parts[i].ctype=-1; + } + + break; + } + } + } + } + } + // diffuse absorbed SLTW + if (parts[i].ctype>0) + { + for ( trade = 0; trade<9; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==t && (parts[i].ctype>parts[r>>8].ctype) && parts[r>>8].ctype>=0 )//diffusion + { + tmp = parts[i].ctype - parts[r>>8].ctype; + if (tmp ==1) + { + parts[r>>8].ctype ++; + parts[i].ctype --; + break; + } + if (tmp>0) + { + parts[r>>8].ctype += tmp/2; + parts[i].ctype -= tmp/2; + break; + } + } + } + } + } + return 0; +} diff --git a/src/elements/rime.cpp b/src/elements/rime.cpp new file mode 100644 index 0000000..617414b --- /dev/null +++ b/src/elements/rime.cpp @@ -0,0 +1,26 @@ +#include "element.h" + +int update_RIME(UPDATE_FUNC_ARGS) { + int r, rx, ry; + parts[i].vx = 0; + parts[i].vy = 0; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPRK) + { + sim->part_change_type(i,x,y,PT_FOG); + parts[i].life = rand()%50 + 60; + } + else if ((r&0xFF)==PT_FOG&&parts[r>>8].life>0) + { + sim->part_change_type(i,x,y,PT_FOG); + parts[i].life = parts[r>>8].life; + } + } + return 0; +} diff --git a/src/elements/shld.cpp b/src/elements/shld.cpp new file mode 100644 index 0000000..cbe8306 --- /dev/null +++ b/src/elements/shld.cpp @@ -0,0 +1,162 @@ +#include "element.h" + +int update_SHLD1(UPDATE_FUNC_ARGS) { + int r, nnx, nny, rx, ry; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + else if ((r&0xFF)==PT_SPRK&&parts[i].life==0) + { + if (55>rand()%200&&parts[i].life==0) + { + sim->part_change_type(i,x,y,PT_SHLD2); + parts[i].life = 7; + } + for ( nnx=-1; nnx<2; nnx++) + for ( nny=-1; nny<2; nny++) + { + if (!pmap[y+ry+nny][x+rx+nnx]) + { + sim->create_part(-1,x+rx+nnx,y+ry+nny,PT_SHLD1); + //parts[pmap[y+ny+nny][x+nx+nnx]>>8].life=7; + } + } + } + else if ((r&0xFF)==PT_SHLD3&&4>rand()%10) + { + sim->part_change_type(i,x,y,PT_SHLD2); + parts[i].life = 7; + } + } + return 0; +} + +int update_SHLD2(UPDATE_FUNC_ARGS) { + int r, nnx, nny, rx, ry, np; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r && parts[i].life>0) + sim->create_part(-1,x+rx,y+ry,PT_SHLD1); + if (!r) + continue; + else if ((r&0xFF)==PT_SPRK&&parts[i].life==0) + { + if (25>rand()%200&&parts[i].life==0) + { + sim->part_change_type(i,x,y,PT_SHLD3); + parts[i].life = 7; + } + for ( nnx=-1; nnx<2; nnx++) + for ( nny=-1; nny<2; nny++) + { + if (!pmap[y+ry+nny][x+rx+nnx]) + { + np = sim->create_part(-1,x+rx+nnx,y+ry+nny,PT_SHLD1); + if (np<0) continue; + parts[np].life=7; + } + } + } + else if ((r&0xFF)==PT_SHLD4&&4>rand()%10) + { + sim->part_change_type(i,x,y,PT_SHLD3); + parts[i].life = 7; + } + } + return 0; +} + +int update_SHLD3(UPDATE_FUNC_ARGS) { + int r, nnx, nny, rx, ry, np; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + { + if (1>rand()%2500) + { + np = sim->create_part(-1,x+rx,y+ry,PT_SHLD1); + if (np<0) continue; + parts[np].life=7; + sim->part_change_type(i,x,y,PT_SHLD2); + } + else + continue; + + } + if ((r&0xFF)==PT_SHLD1 && parts[i].life>3) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_SHLD2); + parts[r>>8].life=7; + } + else if ((r&0xFF)==PT_SPRK&&parts[i].life==0) + { + if (18>rand()%3000&&parts[i].life==0) + { + sim->part_change_type(i,x,y,PT_SHLD4); + parts[i].life = 7; + } + for ( nnx=-1; nnx<2; nnx++) + for ( nny=-1; nny<2; nny++) + { + + if (!pmap[y+ry+nny][x+rx+nnx]) + { + np = sim->create_part(-1,x+rx+nnx,y+ry+nny,PT_SHLD1); + if (np<0) continue; + parts[np].life=7; + } + } + } + } + return 0; +} + +int update_SHLD4(UPDATE_FUNC_ARGS) { + int r, nnx, nny, rx, ry, np; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + { + if (1>rand()%5500) + { + np = sim->create_part(-1,x+rx,y+ry,PT_SHLD1); + if (np<0) continue; + parts[np].life=7; + sim->part_change_type(i,x,y,PT_SHLD2); + } + else + continue; + + } + if ((r&0xFF)==PT_SHLD2 && parts[i].life>3) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_SHLD3); + parts[r>>8].life = 7; + } + else if ((r&0xFF)==PT_SPRK&&parts[i].life==0) + for ( nnx=-1; nnx<2; nnx++) + for ( nny=-1; nny<2; nny++) + { + if (!pmap[y+ry+nny][x+rx+nnx]) + { + np = sim->create_part(-1,x+rx+nnx,y+ry+nny,PT_SHLD1); + if (np<0) continue; + parts[np].life=7; + } + } + } + return 0; +} diff --git a/src/elements/sing.cpp b/src/elements/sing.cpp new file mode 100644 index 0000000..fa6121c --- /dev/null +++ b/src/elements/sing.cpp @@ -0,0 +1,104 @@ +#include "element.h" + +int update_SING(UPDATE_FUNC_ARGS) { + int r, rx, ry, cry, crx, rad, nxi, nxj, nb, j, spawncount; + int singularity = -parts[i].life; + float angle, v; + + if (sim->pv[y/CELL][x/CELL]<singularity) + sim->pv[y/CELL][x/CELL] += 0.1f*(singularity-sim->pv[y/CELL][x/CELL]); + if (y+CELL<YRES && sim->pv[y/CELL+1][x/CELL]<singularity) + sim->pv[y/CELL+1][x/CELL] += 0.1f*(singularity-sim->pv[y/CELL+1][x/CELL]); + if (x+CELL<XRES) + { + sim->pv[y/CELL][x/CELL+1] += 0.1f*(singularity-sim->pv[y/CELL][x/CELL+1]); + if (y+CELL<YRES) + sim->pv[y/CELL+1][x/CELL+1] += 0.1f*(singularity-sim->pv[y/CELL+1][x/CELL+1]); + } + if (y+CELL>0 && sim->pv[y/CELL-1][x/CELL]<singularity) + sim->pv[y/CELL-1][x/CELL] += 0.1f*(singularity-sim->pv[y/CELL-1][x/CELL]); + if (x+CELL>0) + { + sim->pv[y/CELL][x/CELL-1] += 0.1f*(singularity-sim->pv[y/CELL][x/CELL-1]); + if (y+CELL>0) + sim->pv[y/CELL-1][x/CELL-1] += 0.1f*(singularity-sim->pv[y/CELL-1][x/CELL-1]); + } + if (parts[i].life<1) { + //Pop! + for (rx=-2; rx<3; rx++) { + crx = (x/CELL)+rx; + for (ry=-2; ry<3; ry++) { + cry = (y/CELL)+ry; + if (cry > 0 && crx > 0 && crx < (XRES/CELL) && cry < (YRES/CELL)) { + sim->pv[cry][crx] += (float)parts[i].tmp; + } + } + } + spawncount = (parts[i].tmp>255)?255:parts[i].tmp; + if (spawncount>=1) + spawncount = spawncount/8; + spawncount = spawncount*spawncount*M_PI; + for (j=0;j<spawncount;j++) + { + switch(rand()%3) + { + case 0: + nb = sim->create_part(-3, x, y, PT_PHOT); + break; + case 1: + nb = sim->create_part(-3, x, y, PT_NEUT); + break; + case 2: + nb = sim->create_part(-3, x, y, PT_ELEC); + break; + } + if (nb!=-1) { + parts[nb].life = (rand()%300); + parts[nb].temp = MAX_TEMP/2; + angle = rand()*2.0f*M_PI/RAND_MAX; + v = (float)(rand())*5.0f/RAND_MAX; + parts[nb].vx = v*cosf(angle); + parts[nb].vy = v*sinf(angle); + } + else if (sim->pfree==-1) + break;//if we've run out of particles, stop trying to create them - saves a lot of lag on "sing bomb" saves + } + sim->kill_part(i); + return 1; + } + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_DMND&&33>=rand()/(RAND_MAX/100)+1) + { + if ((r&0xFF)==PT_SING && parts[r>>8].life >10) + { + if (parts[i].life+parts[r>>8].life > 255) + continue; + parts[i].life += parts[r>>8].life; + } + else + { + if (parts[i].life+3 > 255) + { + if (parts[r>>8].type!=PT_SING && 1>rand()%100) + { + int np; + np = sim->create_part(r>>8,x+rx,y+ry,PT_SING); + parts[np].life = rand()%50+60; + } + continue; + } + parts[i].life += 3; + parts[i].tmp++; + } + parts[i].temp = restrict_flt(parts[r>>8].temp+parts[i].temp, MIN_TEMP, MAX_TEMP); + sim->kill_part(r>>8); + } + } + return 0; +} diff --git a/src/elements/sltw.cpp b/src/elements/sltw.cpp new file mode 100644 index 0000000..c965fd4 --- /dev/null +++ b/src/elements/sltw.cpp @@ -0,0 +1,30 @@ +#include "element.h" + +int update_SLTW(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SALT && 1>(rand()%10000)) + sim->kill_part(r>>8); + if ((r&0xFF)==PT_PLNT&&5>(rand()%1000)) + sim->kill_part(r>>8); + if (((r&0xFF)==PT_RBDM||(r&0xFF)==PT_LRBD) && !sim->legacy_enable && parts[i].temp>(273.15f+12.0f) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + if ((r&0xFF)==PT_FIRE){ + sim->kill_part(r>>8); + if(1>(rand()%150)){ + sim->kill_part(i); + return 1; + } + } + } + return 0; +} diff --git a/src/elements/smke.cpp b/src/elements/smke.cpp new file mode 100644 index 0000000..d19bd0a --- /dev/null +++ b/src/elements/smke.cpp @@ -0,0 +1,18 @@ +#include "element.h" + +int graphics_SMKE(GRAPHICS_FUNC_ARGS) +{ + *colr = 55; + *colg = 55; + *colb = 55; + + *firea = 75; + *firer = 55; + *fireg = 55; + *fireb = 55; + + *pixel_mode = PMODE_NONE; //Clear default, don't draw pixel + *pixel_mode |= FIRE_BLEND; + //Returning 1 means static, cache as we please + return 1; +}
\ No newline at end of file diff --git a/src/elements/soap.cpp b/src/elements/soap.cpp new file mode 100644 index 0000000..0d31292 --- /dev/null +++ b/src/elements/soap.cpp @@ -0,0 +1,234 @@ +#include "element.h" + +int update_SOAP(UPDATE_FUNC_ARGS) +{ + int r, rx, ry, nr, ng, nb, na; + float tr, tg, tb, ta; + float blend; + + //0x01 - bubble on/off + //0x02 - first mate yes/no + //0x04 - "back" mate yes/no + + if ((parts[i].ctype&1) == 1) + { + if (parts[i].temp>0) + { + if (parts[i].life<=0) + { + if ((parts[i].ctype&6) != 6 && parts[i].ctype>1) + { + int target; + + target = i; + + while((parts[target].ctype&6) != 6 && parts[target].ctype>1) + { + if ((parts[target].ctype&2) == 2) + { + target = parts[target].tmp; + sim->detach(target); + } + + if ((parts[target].ctype&4) == 4) + { + target = parts[target].tmp2; + sim->detach(target); + } + } + } + + if ((parts[i].ctype&6) != 6) + parts[i].ctype = 0; + + if ((parts[i].ctype&6) == 6 && (parts[parts[i].tmp].ctype&6) == 6 && parts[parts[i].tmp].tmp == i) + sim->detach(i); + } + + parts[i].vy -= 0.1f; + + parts[i].vy *= 0.5f; + parts[i].vx *= 0.5f; + } + + if((parts[i].ctype&2) != 2) + { + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + + if ((parts[r>>8].type == PT_SOAP) && ((parts[r>>8].ctype&1) == 1) + && ((parts[r>>8].ctype&4) != 4)) + { + if ((parts[r>>8].ctype&2) == 2) + { + parts[i].tmp = r>>8; + parts[r>>8].tmp2 = i; + + parts[i].ctype |= 2; + parts[r>>8].ctype |= 4; + } + else + { + if ((parts[i].ctype&2) != 2) + { + parts[i].tmp = r>>8; + parts[r>>8].tmp2 = i; + + parts[i].ctype |= 2; + parts[r>>8].ctype |= 4; + } + } + } + } + } + else + { + if (parts[i].life<=0) + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r && !sim->bmap[(y+ry)/CELL][(x+rx)/CELL]) + continue; + + if (parts[i].temp>0) + { + if (sim->bmap[(y+ry)/CELL][(x+rx)/CELL] + || (r && sim->ptypes[r&0xFF].state != ST_GAS + && (r&0xFF) != PT_SOAP && (r&0xFF) != PT_GLAS) + || (parts[r>>8].ctype == 0 && (r&0xFF) == PT_SOAP + && (abs(parts[r>>8].vx)<2 || abs(parts[r>>8].vy)<2))) + { + sim->detach(i); + continue; + } + } + + if ((r&0xFF) == PT_SOAP && parts[r>>8].ctype == 1) + { + int buf; + + buf = parts[i].tmp; + + parts[i].tmp = r>>8; + parts[buf].tmp2 = r>>8; + parts[r>>8].tmp2 = i; + parts[r>>8].tmp = buf; + parts[r>>8].ctype = 7; + } + + if ((r&0xFF) == PT_SOAP && parts[r>>8].ctype == 7 && parts[i].tmp != r>>8 && parts[i].tmp2 != r>>8) + { + int buf; + + parts[parts[i].tmp].tmp2 = parts[r>>8].tmp2; + parts[parts[r>>8].tmp2].tmp = parts[i].tmp; + parts[r>>8].tmp2 = i; + parts[i].tmp = r>>8; + } + } + } + + if((parts[i].ctype&2) == 2) + { + float d, dx, dy; + + dx = parts[i].x - parts[parts[i].tmp].x; + dy = parts[i].y - parts[parts[i].tmp].y; + + d = 9/(pow(dx, 2)+pow(dy, 2)+9)-0.5; + + parts[parts[i].tmp].vx -= dx*d; + parts[parts[i].tmp].vy -= dy*d; + + parts[i].vx += dx*d; + parts[i].vy += dy*d; + + if (((parts[parts[i].tmp].ctype&2) == 2) && ((parts[parts[i].tmp].ctype&1) == 1) + && ((parts[parts[parts[i].tmp].tmp].ctype&2) == 2) && ((parts[parts[parts[i].tmp].tmp].ctype&1) == 1)) + { + int ii; + + ii = parts[parts[parts[i].tmp].tmp].tmp; + + dx = parts[ii].x - parts[parts[i].tmp].x; + dy = parts[ii].y - parts[parts[i].tmp].y; + + d = 81/(pow(dx, 2)+pow(dy, 2)+81)-0.5; + + parts[parts[i].tmp].vx -= dx*d*0.5f; + parts[parts[i].tmp].vy -= dy*d*0.5f; + + parts[ii].vx += dx*d*0.5f; + parts[ii].vy += dy*d*0.5f; + } + } + } + else + { + if (sim->pv[y/CELL][x/CELL]>0.5f || sim->pv[y/CELL][x/CELL]<(-0.5f)) + { + parts[i].ctype = 1; + parts[i].life = 10; + } + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + + if ((r&0xFF) == PT_OIL) + { + float ax, ay; + + parts[i].vy -= 0.1f; + + parts[i].vy *= 0.5f; + parts[i].vx *= 0.5f; + + ax = (parts[i].vx + parts[r>>8].vx)/2; + ay = (parts[i].vy + parts[r>>8].vy)/2; + + parts[i].vx = ax; + parts[i].vy = ay; + parts[r>>8].vx = ax; + parts[r>>8].vy = ay; + } + } + } + + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_SOAP) + { + blend = 0.85f; + tr = (parts[r>>8].dcolour>>16)&0xFF; + tg = (parts[r>>8].dcolour>>8)&0xFF; + tb = (parts[r>>8].dcolour)&0xFF; + ta = (parts[r>>8].dcolour>>24)&0xFF; + + nr = (tr*blend); + ng = (tg*blend); + nb = (tb*blend); + na = (ta*blend); + + parts[r>>8].dcolour = nr<<16 | ng<<8 | nb | na<<24; + } + } + + return 0; +} diff --git a/src/elements/spng.cpp b/src/elements/spng.cpp new file mode 100644 index 0000000..28b3e1b --- /dev/null +++ b/src/elements/spng.cpp @@ -0,0 +1,110 @@ +#include "element.h" + +int update_SPNG(UPDATE_FUNC_ARGS) { + int r, trade, rx, ry, tmp, np; + if (sim->pv[y/CELL][x/CELL]<=3 && sim->pv[y/CELL][x/CELL]>=-3&&parts[i].temp<=374.0f) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_WATR&&33>=rand()/(RAND_MAX/100)+1) + { + parts[i].life++; + sim->kill_part(r>>8); + } + } + } + else + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((!r)&&parts[i].life>=1)//if nothing then create water + { + np = sim->create_part(-1,x+rx,y+ry,PT_WATR); + if (np>-1) parts[i].life--; + } + } + for ( trade = 0; trade<9; trade ++) + { + rx = rand()%5-2; + ry = rand()%5-2; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SPNG&&(parts[i].life>parts[r>>8].life)&&parts[i].life>0)//diffusion + { + tmp = parts[i].life - parts[r>>8].life; + if (tmp ==1) + { + parts[r>>8].life ++; + parts[i].life --; + trade = 9; + } + else if (tmp>0) + { + parts[r>>8].life += tmp/2; + parts[i].life -= tmp/2; + trade = 9; + } + } + } + } + tmp = 0; + if (parts[i].life>0) + { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_FIRE) + { + tmp++; + if (parts[r>>8].life>60) + parts[r>>8].life -= parts[r>>8].life/60; + else if (parts[r>>8].life>2) + parts[r>>8].life--; + } + } + } + if (tmp && parts[i].life>3) + parts[i].life -= parts[i].life/3; + if (tmp>1) + tmp = tmp/2; + if (tmp || parts[i].temp>=374) + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((!r)&&parts[i].life>=1)//if nothing then create steam + { + np = sim->create_part(-1,x+rx,y+ry,PT_WTRV); + if (np>-1) + { + parts[np].temp = parts[i].temp; + tmp--; + parts[i].life--; + parts[i].temp -= 20.0f; + } + } + } + if (tmp>0) + { + if (parts[i].life>tmp) + parts[i].life -= tmp; + else + parts[i].life = 0; + } + return 0; +} diff --git a/src/elements/sprk.cpp b/src/elements/sprk.cpp new file mode 100644 index 0000000..244e831 --- /dev/null +++ b/src/elements/sprk.cpp @@ -0,0 +1,230 @@ +#include "element.h" + +int update_SPRK(UPDATE_FUNC_ARGS) { + int r, rx, ry, rt, conduct_sprk, nearp, pavg, ct = parts[i].ctype; + update_PYRO(UPDATE_FUNC_SUBCALL_ARGS); + + if (parts[i].life<=0) + { + if (ct==PT_WATR||ct==PT_SLTW||ct==PT_PSCN||ct==PT_NSCN||ct==PT_ETRD||ct==PT_INWR) + parts[i].temp = R_TEMP + 273.15f; + if (ct<=0 || ct>=PT_NUM) + ct = PT_METL; + sim->part_change_type(i,x,y,ct); + parts[i].ctype = PT_NONE; + parts[i].life = 4; + if (ct == PT_WATR) + parts[i].life = 64; + if (ct == PT_SLTW) + parts[i].life = 54; + if (ct == PT_SWCH) + parts[i].life = 14; + return 0; + } + if (ct==PT_SPRK) + { + sim->kill_part(i); + return 1; + } + else if (ct==PT_NTCT || ct==PT_PTCT) + { + update_NPTCT(UPDATE_FUNC_SUBCALL_ARGS); + } + else if (ct==PT_ETRD&&parts[i].life==1) + { + nearp = sim->nearest_part(i, PT_ETRD, -1); + if (nearp!=-1 && sim->parts_avg(i, nearp, PT_INSL)!=PT_INSL) + { + sim->create_line(x, y, (int)(parts[nearp].x+0.5f), (int)(parts[nearp].y+0.5f), 0, 0, PT_PLSM, 0); + sim->part_change_type(i,x,y,ct); + ct = parts[i].ctype = PT_NONE; + parts[i].life = 20; + sim->part_change_type(nearp,(int)(parts[nearp].x+0.5f),(int)(parts[nearp].y+0.5f),PT_SPRK); + parts[nearp].life = 9; + parts[nearp].ctype = PT_ETRD; + } + } + else if (ct==PT_NBLE&&parts[i].life<=1) + { + parts[i].life = rand()%150+50; + sim->part_change_type(i,x,y,PT_PLSM); + parts[i].ctype = PT_NBLE; + parts[i].temp = 3500; + sim->pv[y/CELL][x/CELL] += 1; + } + else if (ct==PT_TESC) // tesla coil code + { + if (parts[i].tmp>300) + parts[i].tmp=300; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (r) + continue; + if (rand()%(parts[i].tmp*parts[i].tmp/20+6)==0) + { + int p = sim->create_part(-1, x+rx*2, y+ry*2, PT_LIGH); + if (p!=-1) + { + if(parts[i].tmp<=4) //Prevent Arithmetic errors with zero values + continue; + parts[p].life=rand()%(2+parts[i].tmp/15)+parts[i].tmp/7; + if (parts[i].life>60) + parts[i].life=60; + parts[p].temp=parts[p].life*parts[i].tmp/2.5; + parts[p].tmp2=1; + parts[p].tmp=acos(1.0*rx/sqrt(rx*rx+ry*ry))/M_PI*360; + parts[i].temp-=parts[i].tmp*2+parts[i].temp/5; // slight self-cooling + if (fabs(sim->pv[y/CELL][x/CELL])!=0.0f) + { + if (fabs(sim->pv[y/CELL][x/CELL])<=0.5f) + sim->pv[y/CELL][x/CELL]=0; + else + sim->pv[y/CELL][x/CELL]-=(sim->pv[y/CELL][x/CELL]>0)?0.5:-0.5; + } + } + } + } + } + else if (ct==PT_IRON) { + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF) == PT_DSTW && 30>(rand()/(RAND_MAX/1000))) || + ((r&0xFF) == PT_SLTW && 30>(rand()/(RAND_MAX/1000))) || + ((r&0xFF) == PT_WATR && 30>(rand()/(RAND_MAX/1000)))) + { + if (rand()<RAND_MAX/3) + sim->part_change_type(r>>8,x+rx,y+ry,PT_O2); + else + sim->part_change_type(r>>8,x+rx,y+ry,PT_H2); + } + } + } + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + rt = parts[r>>8].type; + conduct_sprk = 1; + + + pavg = sim->parts_avg(r>>8, i,PT_INSL); + if ((rt==PT_SWCH||(rt==PT_SPRK&&parts[r>>8].ctype==PT_SWCH)) && pavg!=PT_INSL) // make sparked SWCH turn off correctly + { + if (rt==PT_SWCH&&ct==PT_PSCN&&parts[r>>8].life<10) { + parts[r>>8].life = 10; + } + if (ct==PT_NSCN) { + sim->part_change_type(r>>8,x+rx,y+ry,PT_SWCH); + parts[r>>8].ctype = PT_NONE; + parts[r>>8].life = 9; + } + } + else if ((ct==PT_PSCN||ct==PT_NSCN) && (rt==PT_PUMP||rt==PT_GPMP||rt==PT_HSWC||rt==PT_PBCN)) // PROP_PTOGGLE, Maybe? We seem to use 2 different methods for handling actived elements, this one seems better. Yes, use this one for new elements, PCLN is different for compatibility with existing saves + { + if (ct==PT_PSCN) parts[r>>8].life = 10; + else if (ct==PT_NSCN && parts[r>>8].life>=10) parts[r>>8].life = 9; + } + else if ((ct==PT_PSCN||ct==PT_NSCN) && (rt==PT_LCRY&&abs(rx)<2&&abs(ry)<2)) + { + if (ct==PT_PSCN && parts[r>>8].tmp == 0) parts[r>>8].tmp = 2; + else if (ct==PT_NSCN && parts[r>>8].tmp == 3) parts[r>>8].tmp = 1; + } + + + // ct = spark from material, rt = spark to material. Make conduct_sprk = 0 if conduction not allowed + + if (pavg == PT_INSL) conduct_sprk = 0; + if (!((sim->ptypes[rt].properties&PROP_CONDUCTS)||rt==PT_INST||rt==PT_QRTZ)) conduct_sprk = 0; + if (abs(rx)+abs(ry)>=4 &&ct!=PT_SWCH&&rt!=PT_SWCH) + conduct_sprk = 0; + + + if (ct==PT_METL && (rt==PT_NTCT||rt==PT_PTCT||rt==PT_INWR||(rt==PT_SPRK&&(parts[r>>8].ctype==PT_NTCT||parts[r>>8].ctype==PT_PTCT))) && pavg!=PT_INSL) + { + parts[r>>8].temp = 473.0f; + if (rt==PT_NTCT||rt==PT_PTCT) + conduct_sprk = 0; + } + if (ct==PT_NTCT && !(rt==PT_PSCN || rt==PT_NTCT || (rt==PT_NSCN&&parts[i].temp>373.0f))) + conduct_sprk = 0; + if (ct==PT_PTCT && !(rt==PT_PSCN || rt==PT_PTCT || (rt==PT_NSCN&&parts[i].temp<373.0f))) + conduct_sprk = 0; + if (ct==PT_INWR && !(rt==PT_NSCN || rt==PT_INWR || rt==PT_PSCN)) + conduct_sprk = 0; + if (ct==PT_NSCN && rt==PT_PSCN) + conduct_sprk = 0; + if (ct==PT_ETRD && !(rt==PT_METL||rt==PT_ETRD||rt==PT_BMTL||rt==PT_BRMT||rt==PT_LRBD||rt==PT_RBDM||rt==PT_PSCN||rt==PT_NSCN)) + conduct_sprk = 0; + if (ct==PT_INST&&rt!=PT_NSCN) conduct_sprk = 0; + if (ct==PT_SWCH && (rt==PT_PSCN||rt==PT_NSCN||rt==PT_WATR||rt==PT_SLTW||rt==PT_NTCT||rt==PT_PTCT||rt==PT_INWR)) + conduct_sprk = 0; + if (rt==PT_QRTZ && !((ct==PT_NSCN||ct==PT_METL||ct==PT_PSCN||ct==PT_QRTZ) && (parts[r>>8].temp<173.15||sim->pv[(y+ry)/CELL][(x+rx)/CELL]>8))) + conduct_sprk = 0; + if (rt==PT_NTCT && !(ct==PT_NSCN || ct==PT_NTCT || (ct==PT_PSCN&&parts[r>>8].temp>373.0f))) + conduct_sprk = 0; + if (rt==PT_PTCT && !(ct==PT_NSCN || ct==PT_PTCT || (ct==PT_PSCN&&parts[r>>8].temp<373.0f))) + conduct_sprk = 0; + if (rt==PT_INWR && !(ct==PT_NSCN || ct==PT_INWR || ct==PT_PSCN)) + conduct_sprk = 0; + if (rt==PT_INST&&ct!=PT_PSCN) + conduct_sprk = 0; + + if (conduct_sprk) { + if (rt==PT_WATR||rt==PT_SLTW) { + if (parts[r>>8].life==0 && (parts[i].life<2 || ((r>>8)<i && parts[i].life<3))) + { + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + if (rt==PT_WATR) parts[r>>8].life = 6; + else parts[r>>8].life = 5; + parts[r>>8].ctype = rt; + } + } + else if (rt==PT_INST) { + if (parts[i].life>=3&&parts[r>>8].life==0) + { + sim->flood_parts(x+rx,y+ry,PT_SPRK,PT_INST,-1, 0);//spark the wire + } + } + else if (parts[r>>8].life==0 && (parts[i].life<3 || ((r>>8)<i && parts[i].life<4))) { + parts[r>>8].life = 4; + parts[r>>8].ctype = rt; + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + if (parts[r>>8].temp+10.0f<673.0f&&!sim->legacy_enable&&(rt==PT_METL||rt==PT_BMTL||rt==PT_BRMT||rt==PT_PSCN||rt==PT_NSCN||rt==PT_ETRD||rt==PT_NBLE||rt==PT_IRON)) + parts[r>>8].temp = parts[r>>8].temp+10.0f; + } + else if (ct==PT_ETRD && parts[i].life==5) + { + sim->part_change_type(i,x,y,ct); + parts[i].ctype = PT_NONE; + parts[i].life = 20; + parts[r>>8].life = 4; + parts[r>>8].ctype = rt; + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + } + } + } + return 0; +} + +int graphics_SPRK(GRAPHICS_FUNC_ARGS) +{ + *firea = 80; + + *firer = *colr = 170; + *fireg = *colg = 200; + *fireb = *colb = 220; + //*pixel_mode |= FIRE_ADD; + *pixel_mode |= FIRE_ADD; + return 1; +} diff --git a/src/elements/stkm.cpp b/src/elements/stkm.cpp new file mode 100644 index 0000000..322eba1 --- /dev/null +++ b/src/elements/stkm.cpp @@ -0,0 +1,488 @@ +#include "element.h" + +int update_SPAWN(UPDATE_FUNC_ARGS) { + if (!sim->player.spwn) + sim->create_part(-1, x, y, PT_STKM); + + return 0; +} + +int update_STKM(UPDATE_FUNC_ARGS) +{ + run_stickman(&sim->player, UPDATE_FUNC_SUBCALL_ARGS); + return 0; +} + +int graphics_STKM(GRAPHICS_FUNC_ARGS) +{ + /**pixel_mode = PSPEC_STICKMAN; + if ((int)sim->player.elem<PT_NUM) + { + *colr = PIXR(ptypes[sim->player.elem].pcolors); + *colg = PIXG(ptypes[sim->player.elem].pcolors); + *colb = PIXB(ptypes[sim->player.elem].pcolors); + } + else*/ + { + *colr = *colg = *colb = 255; + } + return 1; +} + +int run_stickman(playerst* playerp, UPDATE_FUNC_ARGS) { + int r, rx, ry; + float pp, d; + float dt = 0.9;///(FPSB*FPSB); //Delta time in square + float gvx, gvy; + float gx, gy, dl, dr; + + if ((parts[i].ctype>0 && parts[i].ctype<PT_NUM && sim->ptypes[parts[i].ctype].falldown>0) || parts[i].ctype==SPC_AIR || parts[i].ctype == PT_NEUT || parts[i].ctype == PT_PHOT || parts[i].ctype == PT_LIGH) + playerp->elem = parts[i].ctype; + playerp->frames++; + + //Tempirature handling + if (parts[i].temp<243) + parts[i].life -= 1; + if ((parts[i].temp<309.6f) && (parts[i].temp>=243)) + parts[i].temp += 1; + + //Death + if (parts[i].life<1 || (sim->pv[y/CELL][x/CELL]>=4.5f && playerp->elem != SPC_AIR) ) //If his HP is less that 0 or there is very big wind... + { + for (r=-2; r<=1; r++) + { + sim->create_part(-1, x+r, y-2, playerp->elem); + sim->create_part(-1, x+r+1, y+2, playerp->elem); + sim->create_part(-1, x-2, y+r+1, playerp->elem); + sim->create_part(-1, x+2, y+r, playerp->elem); + } + sim->kill_part(i); //Kill him + return 1; + } + + //Follow gravity + gvx = gvy = 0.0f; + switch (sim->gravityMode) + { + default: + case 0: + gvy = 1; + break; + case 1: + gvy = gvx = 0.0f; + break; + case 2: + { + float gravd; + gravd = 0.01f - hypotf((parts[i].x - XCNTR), (parts[i].y - YCNTR)); + gvx = ((float)(parts[i].x - XCNTR) / gravd); + gvy = ((float)(parts[i].y - YCNTR) / gravd); + } + } + + gvx += sim->gravx[((int)parts[i].y/CELL)*(XRES/CELL)+((int)parts[i].x/CELL)]; + gvy += sim->gravy[((int)parts[i].y/CELL)*(XRES/CELL)+((int)parts[i].x/CELL)]; + + parts[i].vx -= gvx*dt; //Head up! + parts[i].vy -= gvy*dt; + + //Verlet integration + pp = 2*playerp->legs[0]-playerp->legs[2]+playerp->accs[0]*dt*dt; + playerp->legs[2] = playerp->legs[0]; + playerp->legs[0] = pp; + pp = 2*playerp->legs[1]-playerp->legs[3]+playerp->accs[1]*dt*dt; + playerp->legs[3] = playerp->legs[1]; + playerp->legs[1] = pp; + + pp = 2*playerp->legs[4]-playerp->legs[6]+(playerp->accs[2]+gvx)*dt*dt; + playerp->legs[6] = playerp->legs[4]; + playerp->legs[4] = pp; + pp = 2*playerp->legs[5]-playerp->legs[7]+(playerp->accs[3]+gvy)*dt*dt; + playerp->legs[7] = playerp->legs[5]; + playerp->legs[5] = pp; + + pp = 2*playerp->legs[8]-playerp->legs[10]+playerp->accs[4]*dt*dt; + playerp->legs[10] = playerp->legs[8]; + playerp->legs[8] = pp; + pp = 2*playerp->legs[9]-playerp->legs[11]+playerp->accs[5]*dt*dt; + playerp->legs[11] = playerp->legs[9]; + playerp->legs[9] = pp; + + pp = 2*playerp->legs[12]-playerp->legs[14]+(playerp->accs[6]+gvx)*dt*dt; + playerp->legs[14] = playerp->legs[12]; + playerp->legs[12] = pp; + pp = 2*playerp->legs[13]-playerp->legs[15]+(playerp->accs[7]+gvy)*dt*dt; + playerp->legs[15] = playerp->legs[13]; + playerp->legs[13] = pp; + + //Setting accseleration to 0 + playerp->accs[0] = 0; + playerp->accs[1] = 0; + + playerp->accs[2] = 0; + playerp->accs[3] = 0; + + playerp->accs[4] = 0; + playerp->accs[5] = 0; + + playerp->accs[6] = 0; + playerp->accs[7] = 0; + + gx = (playerp->legs[4] + playerp->legs[12])/2 - gvy; + gy = (playerp->legs[5] + playerp->legs[13])/2 + gvx; + dl = pow(gx - playerp->legs[4], 2) + pow(gy - playerp->legs[5], 2); + dr = pow(gx - playerp->legs[12], 2) + pow(gy - playerp->legs[13], 2); + + //Go left + if (((int)(playerp->comm)&0x01) == 0x01) + { + if (dl>dr) + { + if (!sim->eval_move(PT_DUST, playerp->legs[4], playerp->legs[5], NULL)) + { + playerp->accs[2] = -3*gvy-3*gvx; + playerp->accs[3] = 3*gvx-3*gvy; + playerp->accs[0] = -gvy; + playerp->accs[1] = gvx; + } + } + else + { + if (!sim->eval_move(PT_DUST, playerp->legs[12], playerp->legs[13], NULL)) + { + playerp->accs[6] = -3*gvy-3*gvx; + playerp->accs[7] = 3*gvx-3*gvy; + playerp->accs[0] = -gvy; + playerp->accs[1] = gvx; + } + } + } + + //Go right + if (((int)(playerp->comm)&0x02) == 0x02) + { + if (dl<dr) + { + if (!sim->eval_move(PT_DUST, playerp->legs[4], playerp->legs[5], NULL)) + { + playerp->accs[2] = 3*gvy-3*gvx; + playerp->accs[3] = -3*gvx-3*gvy; + playerp->accs[0] = gvy; + playerp->accs[1] = -gvx; + } + } + else + { + if (!sim->eval_move(PT_DUST, playerp->legs[12], playerp->legs[13], NULL)) + { + playerp->accs[6] = 3*gvy-3*gvx; + playerp->accs[7] = -3*gvx-3*gvy; + playerp->accs[0] = gvy; + playerp->accs[1] = -gvx; + } + } + } + + //Jump + if (((int)(playerp->comm)&0x04) == 0x04 && + (!sim->eval_move(PT_DUST, playerp->legs[4], playerp->legs[5], NULL) || !sim->eval_move(PT_DUST, playerp->legs[12], playerp->legs[13], NULL))) + { + parts[i].vy -= 4*gvy; + playerp->accs[3] -= gvy; + playerp->accs[7] -= gvy; + } + + //Charge detector wall if foot inside + if (sim->bmap[(int)(playerp->legs[5]+0.5)/CELL][(int)(playerp->legs[4]+0.5)/CELL]==WL_DETECT) + sim->set_emap((int)playerp->legs[4]/CELL, (int)playerp->legs[5]/CELL); + if (sim->bmap[(int)(playerp->legs[13]+0.5)/CELL][(int)(playerp->legs[12]+0.5)/CELL]==WL_DETECT) + sim->set_emap((int)(playerp->legs[12]+0.5)/CELL, (int)(playerp->legs[13]+0.5)/CELL); + + //Searching for particles near head + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + r = sim->photons[y+ry][x+rx]; + + if (!r && !sim->bmap[(y+ry)/CELL][(x+rx)/CELL]) + continue; + + if (sim->ptypes[r&0xFF].falldown!=0 || sim->ptypes[r&0xFF].state == ST_GAS || (r&0xFF) == PT_NEUT || (r&0xFF) == PT_PHOT) + { + playerp->elem = r&0xFF; //Current element + } + if ((r&0xFF)==PT_TESC || (r&0xFF)==PT_LIGH) + playerp->elem = PT_LIGH; + if ((r&0xFF) == PT_PLNT && parts[i].life<100) //Plant gives him 5 HP + { + if (parts[i].life<=95) + parts[i].life += 5; + else + parts[i].life = 100; + sim->kill_part(r>>8); + } + + if ((r&0xFF) == PT_NEUT) + { + if (parts[i].life<=100) parts[i].life -= (102-parts[i].life)/2; + else parts[i].life *= 0.9f; + sim->kill_part(r>>8); + } + if (sim->bmap[(ry+y)/CELL][(rx+x)/CELL]==WL_FAN) + playerp->elem = SPC_AIR; + if ((r&0xFF)==PT_PRTI) + STKM_interact(sim, playerp, i, rx, ry); + if (!parts[i].type)//STKM_interact may kill STKM + return 1; + } + + //Head position + rx = x + 3*((((int)playerp->pcomm)&0x02) == 0x02) - 3*((((int)playerp->pcomm)&0x01) == 0x01); + ry = y - 3*(playerp->pcomm == 0); + + //Spawn + if (((int)(playerp->comm)&0x08) == 0x08) + { + ry -= 2*(rand()%2)+1; + r = pmap[ry][rx]; + if (sim->ptypes[r&0xFF].state == ST_SOLID) + { + sim->create_part(-1, rx, ry, PT_SPRK); + playerp->frames = 0; + } + else + { + int np = -1; + if (playerp->elem == SPC_AIR) + sim->create_parts(rx + 3*((((int)playerp->pcomm)&0x02) == 0x02) - 3*((((int)playerp->pcomm)&0x01) == 0x01), ry, 4, 4, SPC_AIR, 0); + else if (playerp->elem==PT_LIGH && playerp->frames<30)//limit lightning creation rate + np = -1; + else + np = sim->create_part(-1, rx, ry, playerp->elem); + if ( (np < NPART) && np>=0) + { + if (playerp->elem == PT_PHOT) + { + int random = abs(rand()%3-1)*3; + if (random==0) + { + sim->kill_part(np); + } + else + { + parts[np].vy = 0; + if (((int)playerp->pcomm)&(0x01|0x02)) + parts[np].vx = (((((int)playerp->pcomm)&0x02) == 0x02) - (((int)(playerp->pcomm)&0x01) == 0x01))*random; + else + parts[np].vx = random; + } + } + else if (playerp->elem == PT_LIGH) + { + float angle; + int power = 100; + if (gvx!=0 || gvy!=0) + angle = atan2(gvx, gvy)*180.0f/M_PI; + else + angle = rand()%360; + if (((int)playerp->comm)&0x01) + angle += 180; + if (angle>360) + angle-=360; + if (angle<0) + angle+=360; + parts[np].tmp = angle; + parts[np].life=rand()%(2+power/15)+power/7; + parts[np].temp=parts[np].life*power/2.5; + parts[np].tmp2=1; + } + else if (playerp->elem != SPC_AIR) + { + parts[np].vx -= -gvy*(5*((((int)playerp->pcomm)&0x02) == 0x02) - 5*(((int)(playerp->pcomm)&0x01) == 0x01)); + parts[np].vy -= gvx*(5*((((int)playerp->pcomm)&0x02) == 0x02) - 5*(((int)(playerp->pcomm)&0x01) == 0x01)); + parts[i].vx -= (sim->ptypes[(int)playerp->elem].weight*parts[np].vx)/1000; + } + playerp->frames = 0; + } + + } + } + + //Simulation of joints + d = 25/(pow((playerp->legs[0]-playerp->legs[4]), 2) + pow((playerp->legs[1]-playerp->legs[5]), 2)+25) - 0.5; //Fast distance + playerp->legs[4] -= (playerp->legs[0]-playerp->legs[4])*d; + playerp->legs[5] -= (playerp->legs[1]-playerp->legs[5])*d; + playerp->legs[0] += (playerp->legs[0]-playerp->legs[4])*d; + playerp->legs[1] += (playerp->legs[1]-playerp->legs[5])*d; + + d = 25/(pow((playerp->legs[8]-playerp->legs[12]), 2) + pow((playerp->legs[9]-playerp->legs[13]), 2)+25) - 0.5; + playerp->legs[12] -= (playerp->legs[8]-playerp->legs[12])*d; + playerp->legs[13] -= (playerp->legs[9]-playerp->legs[13])*d; + playerp->legs[8] += (playerp->legs[8]-playerp->legs[12])*d; + playerp->legs[9] += (playerp->legs[9]-playerp->legs[13])*d; + + d = 36/(pow((playerp->legs[0]-parts[i].x), 2) + pow((playerp->legs[1]-parts[i].y), 2)+36) - 0.5; + parts[i].vx -= (playerp->legs[0]-parts[i].x)*d; + parts[i].vy -= (playerp->legs[1]-parts[i].y)*d; + playerp->legs[0] += (playerp->legs[0]-parts[i].x)*d; + playerp->legs[1] += (playerp->legs[1]-parts[i].y)*d; + + d = 36/(pow((playerp->legs[8]-parts[i].x), 2) + pow((playerp->legs[9]-parts[i].y), 2)+36) - 0.5; + parts[i].vx -= (playerp->legs[8]-parts[i].x)*d; + parts[i].vy -= (playerp->legs[9]-parts[i].y)*d; + playerp->legs[8] += (playerp->legs[8]-parts[i].x)*d; + playerp->legs[9] += (playerp->legs[9]-parts[i].y)*d; + + if (!sim->eval_move(PT_DUST, playerp->legs[4], playerp->legs[5], NULL)) + { + playerp->legs[4] = playerp->legs[6]; + playerp->legs[5] = playerp->legs[7]; + } + + if (!sim->eval_move(PT_DUST, playerp->legs[12], playerp->legs[13], NULL)) + { + playerp->legs[12] = playerp->legs[14]; + playerp->legs[13] = playerp->legs[15]; + } + + //This makes stick man "pop" from obstacles + if (!sim->eval_move(PT_DUST, playerp->legs[4], playerp->legs[5], NULL)) + { + float t; + t = playerp->legs[4]; playerp->legs[4] = playerp->legs[6]; playerp->legs[6] = t; + t = playerp->legs[5]; playerp->legs[5] = playerp->legs[7]; playerp->legs[7] = t; + } + + if (!sim->eval_move(PT_DUST, playerp->legs[12], playerp->legs[13], NULL)) + { + float t; + t = playerp->legs[12]; playerp->legs[12] = playerp->legs[14]; playerp->legs[14] = t; + t = playerp->legs[13]; playerp->legs[13] = playerp->legs[15]; playerp->legs[15] = t; + } + + //Keeping legs distance + if ((pow((playerp->legs[4] - playerp->legs[12]), 2) + pow((playerp->legs[5]-playerp->legs[13]), 2))<16) + { + float tvx, tvy; + tvx = -gvy; + tvy = gvx; + + if (tvx || tvy) + { + playerp->accs[2] -= 0.2*tvx/hypot(tvx, tvy); + playerp->accs[3] -= 0.2*tvy/hypot(tvx, tvy); + + playerp->accs[6] += 0.2*tvx/hypot(tvx, tvy); + playerp->accs[7] += 0.2*tvy/hypot(tvx, tvy); + } + } + + if ((pow((playerp->legs[0] - playerp->legs[8]), 2) + pow((playerp->legs[1]-playerp->legs[9]), 2))<16) + { + float tvx, tvy; + tvx = -gvy; + tvy = gvx; + + if (tvx || tvy) + { + playerp->accs[0] -= 0.2*tvx/hypot(tvx, tvy); + playerp->accs[1] -= 0.2*tvy/hypot(tvx, tvy); + + playerp->accs[4] += 0.2*tvx/hypot(tvx, tvy); + playerp->accs[5] += 0.2*tvy/hypot(tvx, tvy); + } + } + + //If legs touch something + STKM_interact(sim, playerp, i, (int)(playerp->legs[4]+0.5), (int)(playerp->legs[5]+0.5)); + STKM_interact(sim, playerp, i, (int)(playerp->legs[12]+0.5), (int)(playerp->legs[13]+0.5)); + STKM_interact(sim, playerp, i, (int)(playerp->legs[4]+0.5), (int)playerp->legs[5]); + STKM_interact(sim, playerp, i, (int)(playerp->legs[12]+0.5), (int)playerp->legs[13]); + if (!parts[i].type) + return 1; + + parts[i].ctype = playerp->elem; + return 0; +} + +void STKM_interact(Simulation * sim, playerst* playerp, int i, int x, int y) +{ + int r; + if (x<0 || y<0 || x>=XRES || y>=YRES || !sim->parts[i].type) + return; + r = sim->pmap[y][x]; + if (r) + { + if ((r&0xFF)==PT_SPRK && playerp->elem!=PT_LIGH) //If on charge + { + sim->parts[i].life -= (int)(rand()*20/RAND_MAX)+32; + } + + if (sim->ptypes[r&0xFF].hconduct && ((playerp->elem!=PT_LIGH && sim->parts[r>>8].temp>=323) || sim->parts[r>>8].temp<=243)) + { + sim->parts[i].life -= 2; + playerp->accs[3] -= 1; + } + + if (sim->ptypes[r&0xFF].properties&PROP_DEADLY) + switch (r&0xFF) + { + case PT_ACID: + sim->parts[i].life -= 5; + break; + default: + sim->parts[i].life -= 1; + break; + } + + if (sim->ptypes[r&0xFF].properties&PROP_RADIOACTIVE) + sim->parts[i].life -= 1; + + if ((r&0xFF)==PT_PRTI && sim->parts[i].type) + { + int nnx, count=1;//gives rx=0, ry=1 in update_PRTO + sim->parts[r>>8].tmp = (int)((sim->parts[r>>8].temp-73.15f)/100+1); + if (sim->parts[r>>8].tmp>=CHANNELS) sim->parts[r>>8].tmp = CHANNELS-1; + else if (sim->parts[r>>8].tmp<0) sim->parts[r>>8].tmp = 0; + for (nnx=0; nnx<80; nnx++) + if (!sim->portalp[sim->parts[r>>8].tmp][count][nnx].type) + { + sim->portalp[sim->parts[r>>8].tmp][count][nnx] = sim->parts[i]; + sim->kill_part(i); + playerp->spwn = 1;//stop SPWN creating a new STKM while he is in portal + break; + } + } + } +} + +void STKM_init_legs(Simulation * sim, playerst* playerp, int i) +{ + int x, y; + + x = (int)(sim->parts[i].x+0.5f); + y = (int)(sim->parts[i].y+0.5f); + + playerp->legs[0] = x-1; + playerp->legs[1] = y+6; + playerp->legs[2] = x-1; + playerp->legs[3] = y+6; + + playerp->legs[4] = x-3; + playerp->legs[5] = y+12; + playerp->legs[6] = x-3; + playerp->legs[7] = y+12; + + playerp->legs[8] = x+1; + playerp->legs[9] = y+6; + playerp->legs[10] = x+1; + playerp->legs[11] = y+6; + + playerp->legs[12] = x+3; + playerp->legs[13] = y+12; + playerp->legs[14] = x+3; + playerp->legs[15] = y+12; +} diff --git a/src/elements/stkm2.cpp b/src/elements/stkm2.cpp new file mode 100644 index 0000000..967bea2 --- /dev/null +++ b/src/elements/stkm2.cpp @@ -0,0 +1,29 @@ +#include "element.h" + +int update_SPAWN2(UPDATE_FUNC_ARGS) { + if (!sim->player2.spwn) + sim->create_part(-1, x, y, PT_STKM2); + + return 0; +} + +int update_STKM2(UPDATE_FUNC_ARGS) { + run_stickman(&sim->player2, UPDATE_FUNC_SUBCALL_ARGS); + return 0; +} + +int graphics_STKM2(GRAPHICS_FUNC_ARGS) +{ + /**pixel_mode = PSPEC_STICKMAN; + if ((int)sim->player2.elem<PT_NUM) + { + *colr = PIXR(ptypes[sim->player2.elem].pcolors); + *colg = PIXG(ptypes[sim->player2.elem].pcolors); + *colb = PIXB(ptypes[sim->player2.elem].pcolors); + } + else*/ + { + *colr = *colg = *colb = 255; + } + return 1; +} diff --git a/src/elements/stor.cpp b/src/elements/stor.cpp new file mode 100644 index 0000000..66eb072 --- /dev/null +++ b/src/elements/stor.cpp @@ -0,0 +1,43 @@ +#include "element.h" + +int update_STOR(UPDATE_FUNC_ARGS) { + int r, rx, ry, np, rx1, ry1; + if(parts[i].life && !parts[i].tmp) + parts[i].life--; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if ((r>>8)>=NPART || !r) + continue; + if (!parts[i].tmp && !parts[i].life && (r&0xFF)!=PT_STOR && !(sim->ptypes[(r&0xFF)].properties&TYPE_SOLID) && (!parts[i].ctype || (r&0xFF)==parts[i].ctype)) + { + parts[i].tmp = parts[r>>8].type; + parts[i].temp = parts[r>>8].temp; + parts[i].flags = parts[r>>8].life; + parts[i].pavg[0] = parts[r>>8].tmp; + parts[i].pavg[1] = parts[r>>8].ctype; + sim->kill_part(r>>8); + } + if(parts[i].tmp && (r&0xFF)==PT_SPRK && parts[r>>8].ctype==PT_PSCN) + { + for(ry1 = 1; ry1 >= -1; ry1--){ + for(rx1 = 0; rx1 >= -1 && rx1 <= 1; rx1 = -rx1-rx1+1){ // Oscilate the X starting at 0, 1, -1, 3, -5, etc (Though stop at -1) + np = sim->create_part(-1,x+rx1,y+ry1,parts[i].tmp); + if (np!=-1) + { + parts[np].temp = parts[i].temp; + parts[np].life = parts[i].flags; + parts[np].tmp = parts[i].pavg[0]; + parts[np].ctype = parts[i].pavg[1]; + parts[i].tmp = 0; + parts[i].life = 10; + break; + } + } + } + } + } + return 0; +} diff --git a/src/elements/swch.cpp b/src/elements/swch.cpp new file mode 100644 index 0000000..ee2c467 --- /dev/null +++ b/src/elements/swch.cpp @@ -0,0 +1,41 @@ +#include "element.h" + +int update_SWCH(UPDATE_FUNC_ARGS) { + int r, rt, rx, ry; + if (parts[i].life>0 && parts[i].life!=10) + parts[i].life--; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->parts_avg(i,r>>8,PT_INSL)!=PT_INSL) { + rt = r&0xFF; + if (rt==PT_SWCH) + { + if (parts[i].life>=10&&parts[r>>8].life<10&&parts[r>>8].life>0) + parts[i].life = 9; + else if (parts[i].life==0&&parts[r>>8].life==10) + parts[i].life = 10; + } + else if (rt==PT_SPRK&&parts[i].life==10&&parts[r>>8].ctype!=PT_PSCN&&parts[r>>8].ctype!=PT_NSCN) { + sim->part_change_type(i,x,y,PT_SPRK); + parts[i].ctype = PT_SWCH; + parts[i].life = 4; + } + } + } + //turn off SWCH from two red BRAYS + if (parts[i].life==10 && (!(pmap[y-1][x-1]&0xFF) && ((pmap[y-1][x]&0xFF)==PT_BRAY&&parts[pmap[y-1][x]>>8].tmp==2) && !(pmap[y-1][x+1]&0xFF) && ((pmap[y][x+1]&0xFF)==PT_BRAY&&parts[pmap[y][x+1]>>8].tmp==2))) + { + parts[i].life = 9; + } + //turn on SWCH from two red BRAYS + else if (parts[i].life<=5 && (!(pmap[y-1][x-1]&0xFF) && (((pmap[y-1][x]&0xFF)==PT_BRAY&&parts[pmap[y-1][x]>>8].tmp==2) || ((pmap[y+1][x]&0xFF)==PT_BRAY&&parts[pmap[y+1][x]>>8].tmp==2)) && !(pmap[y-1][x+1]&0xFF) && (((pmap[y][x+1]&0xFF)==PT_BRAY&&parts[pmap[y][x+1]>>8].tmp==2) || ((pmap[y][x-1]&0xFF)==PT_BRAY&&parts[pmap[y][x-1]>>8].tmp==2)))) + { + parts[i].life = 14; + } + return 0; +} diff --git a/src/elements/thdr.cpp b/src/elements/thdr.cpp new file mode 100644 index 0000000..f7f95b4 --- /dev/null +++ b/src/elements/thdr.cpp @@ -0,0 +1,38 @@ +#include "element.h" + +int update_THDR(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((sim->ptypes[r&0xFF].properties&PROP_CONDUCTS) && parts[r>>8].life==0 && !((r&0xFF)==PT_WATR||(r&0xFF)==PT_SLTW) && parts[r>>8].ctype!=PT_SPRK) + { + parts[i].type = PT_NONE; + parts[r>>8].ctype = parts[r>>8].type; + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + parts[r>>8].life = 4; + } + else if ((r&0xFF)!=PT_CLNE&&(r&0xFF)!=PT_THDR&&(r&0xFF)!=PT_SPRK&&(r&0xFF)!=PT_DMND&&(r&0xFF)!=PT_FIRE&&(r&0xFF)!=PT_NEUT&&(r&0xFF)!=PT_PHOT&&(r&0xFF)) + { + sim->pv[y/CELL][x/CELL] += 100.0f; + if (sim->legacy_enable&&1>(rand()%200)) + { + parts[i].life = rand()%50+120; + sim->part_change_type(i,x,y,PT_FIRE); + } + else + { + parts[i].type = PT_NONE; + } + } + } + if (parts[i].type==PT_NONE) { + sim->kill_part(i); + return 1; + } + return 0; +} diff --git a/src/elements/thrm.cpp b/src/elements/thrm.cpp new file mode 100644 index 0000000..91939e6 --- /dev/null +++ b/src/elements/thrm.cpp @@ -0,0 +1,29 @@ +#include "element.h" + +int update_THRM(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_FIRE || (r&0xFF)==PT_PLSM || (r&0xFF)==PT_LAVA)) // TODO: could this go in update_PYRO? + { + if (1>(rand()%500)) { + sim->part_change_type(i,x,y,PT_LAVA); + parts[i].ctype = PT_BMTL; + parts[i].temp = 3500.0f; + sim->pv[y/CELL][x/CELL] += 50.0f; + } else { + sim->part_change_type(i,x,y,PT_LAVA); + parts[i].life = 400; + parts[i].ctype = PT_THRM; + parts[i].temp = 3500.0f; + parts[i].tmp = 20; + } + } + } + return 0; +} diff --git a/src/elements/uran.cpp b/src/elements/uran.cpp new file mode 100644 index 0000000..a8b2a06 --- /dev/null +++ b/src/elements/uran.cpp @@ -0,0 +1,10 @@ +#include "element.h" + +int update_URAN(UPDATE_FUNC_ARGS) { + if (!sim->legacy_enable && sim->pv[y/CELL][x/CELL]>0.0f) + { + float atemp = parts[i].temp + (-MIN_TEMP); + parts[i].temp = restrict_flt((atemp*(1+(sim->pv[y/CELL][x/CELL]/2000)))+MIN_TEMP, MIN_TEMP, MAX_TEMP); + } + return 0; +} diff --git a/src/elements/vine.cpp b/src/elements/vine.cpp new file mode 100644 index 0000000..165d391 --- /dev/null +++ b/src/elements/vine.cpp @@ -0,0 +1,19 @@ +#include "element.h" + +int update_VINE(UPDATE_FUNC_ARGS) { + int r, np, rx =(rand()%3)-1, ry=(rand()%3)-1; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (1>rand()%15) + sim->part_change_type(i,x,y,PT_PLNT); + else if (!r) + { + np = sim->create_part(-1,x+rx,y+ry,PT_VINE); + if (np<0) return 0; + parts[np].temp = parts[i].temp; + sim->part_change_type(i,x,y,PT_PLNT); + } + } + return 0; +} diff --git a/src/elements/warp.cpp b/src/elements/warp.cpp new file mode 100644 index 0000000..ddc1b81 --- /dev/null +++ b/src/elements/warp.cpp @@ -0,0 +1,28 @@ +#include "element.h" + +int update_WARP(UPDATE_FUNC_ARGS) { + int trade, r, rx, ry; + for ( trade = 0; trade<5; trade ++) + { + rx = rand()%3-1; + ry = rand()%3-1; + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)!=PT_WARP&&(r&0xFF)!=PT_STKM&&(r&0xFF)!=PT_STKM2&&(r&0xFF)!=PT_DMND&&(r&0xFF)!=PT_CLNE&&(r&0xFF)!=PT_BCLN&&(r&0xFF)!=PT_PCLN&&(10>=rand()%200)) + { + parts[i].x = parts[r>>8].x; + parts[i].y = parts[r>>8].y; + parts[r>>8].x = x; + parts[r>>8].y = y; + parts[i].life += 4; + pmap[y][x] = r; + pmap[y+ry][x+rx] = (i<<8)|parts[i].type; + trade = 5; + } + } + } + return 0; +} diff --git a/src/elements/watr.cpp b/src/elements/watr.cpp new file mode 100644 index 0000000..09b66a9 --- /dev/null +++ b/src/elements/watr.cpp @@ -0,0 +1,36 @@ +#include "element.h" + +int update_WATR(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_SALT && 1>(rand()%250)) + { + sim->part_change_type(i,x,y,PT_SLTW); + sim->part_change_type(r>>8,x+rx,y+ry,PT_SLTW); + } + if (((r&0xFF)==PT_RBDM||(r&0xFF)==PT_LRBD) && (sim->legacy_enable||parts[i].temp>(273.15f+12.0f)) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + if ((r&0xFF)==PT_FIRE){ + sim->kill_part(r>>8); + if(1>(rand()%150)){ + sim->kill_part(i); + return 1; + } + } + /*if ((r&0xFF)==PT_CNCT && 1>(rand()%500)) Concrete+Water to paste, not very popular + { + part_change_type(i,x,y,PT_PSTE); + sim.kill_part(r>>8); + }*/ + } + return 0; +} diff --git a/src/elements/wifi.cpp b/src/elements/wifi.cpp new file mode 100644 index 0000000..ee5e264 --- /dev/null +++ b/src/elements/wifi.cpp @@ -0,0 +1,35 @@ +#include "element.h" + +int update_WIFI(UPDATE_FUNC_ARGS) { + int r, rx, ry; + parts[i].tmp = (int)((parts[i].temp-73.15f)/100+1); + if (parts[i].tmp>=CHANNELS) parts[i].tmp = CHANNELS-1; + else if (parts[i].tmp<0) parts[i].tmp = 0; + for (rx=-1; rx<2; rx++) + for (ry=-1; ry<2; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (sim->wireless[parts[i].tmp][0]) + { + if (((r&0xFF)==PT_NSCN||(r&0xFF)==PT_PSCN||(r&0xFF)==PT_INWR)&&parts[r>>8].life==0 && sim->wireless[parts[i].tmp][0]) + { + parts[r>>8].ctype = r&0xFF; + sim->part_change_type(r>>8,x+rx,y+ry,PT_SPRK); + parts[r>>8].life = 4; + } + } + else + { + if ((r&0xFF)==PT_SPRK && parts[r>>8].ctype!=PT_NSCN && parts[r>>8].life>=3) + { + sim->wireless[parts[i].tmp][0] = 1; + sim->wireless[parts[i].tmp][1] = 1; + //ISWIRE = 1; + } + } + } + return 0; +} diff --git a/src/elements/wire.cpp b/src/elements/wire.cpp new file mode 100644 index 0000000..49d3720 --- /dev/null +++ b/src/elements/wire.cpp @@ -0,0 +1,67 @@ +#include "element.h" + +int update_WIRE(UPDATE_FUNC_ARGS) { + int s,r,rx,ry,count; + /* + 0: wire + 1: spark head + 2: spark tail + + tmp is previous state, ctype is current state + */ + //parts[i].tmp=parts[i].ctype; + parts[i].ctype=0; + if(parts[i].tmp==1) + { + parts[i].ctype=2; + } + if(parts[i].tmp==2) + { + parts[i].ctype=0; + } + + count=0; + for(rx=-1; rx<2; rx++) + for(ry=-1; ry<2; ry++) + { + if(x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if((r&0xFF)==PT_SPRK && parts[r>>8].ctype==PT_PSCN){parts[i].ctype=1; parts[r>>8].life=0; return 0;} + else if((r&0xFF)==PT_NSCN && parts[i].tmp==1){sim->create_part(-1, x+rx, y+ry, PT_SPRK);} + else if((r&0xFF)==PT_WIRE && parts[r>>8].tmp==1 && !parts[i].tmp){count++;} + } + } + if(count==1 || count==2) + parts[i].ctype=1; + return 0; +} + +int graphics_WIRE(GRAPHICS_FUNC_ARGS) +{ + if (cpart->ctype==0) + { + *colr = 255; + *colg = 204; + *colb = 0; + return 0; + } + if (cpart->ctype==1) + { + *colr = 50; + *colg = 100; + *colb = 255; + //*pixel_mode |= PMODE_GLOW; + return 0; + } + if (cpart->ctype==2) + { + *colr = 255; + *colg = 100; + *colb = 50; + //*pixel_mode |= PMODE_GLOW; + return 0; + } +} diff --git a/src/elements/wtrv.cpp b/src/elements/wtrv.cpp new file mode 100644 index 0000000..de0eae4 --- /dev/null +++ b/src/elements/wtrv.cpp @@ -0,0 +1,21 @@ +#include "element.h" + +int update_WTRV(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if (((r&0xFF)==PT_RBDM||(r&0xFF)==PT_LRBD) && !sim->legacy_enable && parts[i].temp>(273.15f+12.0f) && 1>(rand()%500)) + { + sim->part_change_type(i,x,y,PT_FIRE); + parts[i].life = 4; + } + } + if(parts[i].temp>1273&&parts[i].ctype==PT_FIRE) + parts[i].temp-=parts[i].temp/1000; + return 0; +} diff --git a/src/elements/yest.cpp b/src/elements/yest.cpp new file mode 100644 index 0000000..c6c7db6 --- /dev/null +++ b/src/elements/yest.cpp @@ -0,0 +1,21 @@ +#include "element.h" + +int update_YEST(UPDATE_FUNC_ARGS) { + int r, rx, ry; + for (rx=-2; rx<3; rx++) + for (ry=-2; ry<3; ry++) + if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) + { + r = pmap[y+ry][x+rx]; + if (!r) + continue; + if ((r&0xFF)==PT_DYST && 1>(rand()%30) && !sim->legacy_enable) + { + sim->part_change_type(i,x,y,PT_DYST); + } + } + if (parts[i].temp>303&&parts[i].temp<317) { + sim->create_part(-1, x+rand()%3-1, y+rand()%3-1, PT_YEST); + } + return 0; +} diff --git a/src/game/GameController.cpp b/src/game/GameController.cpp new file mode 100644 index 0000000..becb540 --- /dev/null +++ b/src/game/GameController.cpp @@ -0,0 +1,62 @@ + +#include <iostream> +#include <queue> +#include "Config.h" +#include "GameController.h" +#include "GameModel.h" +#include "interface/Point.h" + +using namespace std; + +GameController::GameController() +{ + gameView = new GameView(); + gameModel = new GameModel(); + + gameView->AttachController(this); + gameModel->AddObserver(gameView); + + sim = new Simulation(); +} + +GameView * GameController::GetView() +{ + return gameView; +} + +void GameController::DrawPoints(queue<ui::Point*> & pointQueue) +{ + Simulation * sim = gameModel->GetSimulation(); + int activeElement = gameModel->GetActiveElement(); + if(!pointQueue.empty()) + { + ui::Point * sPoint = NULL; + while(!pointQueue.empty()) + { + ui::Point * fPoint = pointQueue.front(); + pointQueue.pop(); + if(sPoint) + { + sim->create_line(fPoint->X, fPoint->Y, sPoint->X, sPoint->Y, 1, 1, activeElement, 0); + delete sPoint; + } + else + { + sim->create_parts(fPoint->X, fPoint->Y, 1, 1, activeElement, 0); + } + sPoint = fPoint; + } + if(sPoint) + delete sPoint; + } +} + +void GameController::Tick() +{ + gameModel->GetSimulation()->update_particles(); +} + +void GameController::SetPaused(bool pauseState) +{ + gameModel->SetPaused(pauseState); +} diff --git a/src/game/GameController.h b/src/game/GameController.h new file mode 100644 index 0000000..c3c8273 --- /dev/null +++ b/src/game/GameController.h @@ -0,0 +1,28 @@ +#ifndef GAMECONTROLLER_H +#define GAMECONTROLLER_H + +#include <queue> +#include "GameView.h" +#include "GameModel.h" +#include "interface/Point.h" +#include "Simulation.h" + +using namespace std; + +class GameModel; +class GameView; +class GameController +{ +private: + Simulation * sim; + GameView * gameView; + GameModel * gameModel; +public: + GameController(); + GameView * GetView(); + void DrawPoints(queue<ui::Point*> & pointQueue); + void Tick(); + void SetPaused(bool pauseState); +}; + +#endif // GAMECONTROLLER_H diff --git a/src/game/GameModel.cpp b/src/game/GameModel.cpp new file mode 100644 index 0000000..96b29a9 --- /dev/null +++ b/src/game/GameModel.cpp @@ -0,0 +1,75 @@ +#include "interface/Engine.h" +#include "GameModel.h" +#include "GameView.h" +#include "Simulation.h" +#include "Renderer.h" + +GameModel::GameModel(): + activeElement(1) +{ + sim = new Simulation(); + ren = new Renderer(ui::Engine::Ref().g, sim); +} + +void GameModel::AddObserver(GameView * observer){ + observers.push_back(observer); + + observer->NotifySimulationChanged(this); + observer->NotifyRendererChanged(this); + observer->NotifyPausedChanged(this); +} + +int GameModel::GetActiveElement() +{ + return activeElement; +} + +void GameModel::SetActiveElement(int element) +{ + activeElement = element; +} + +Simulation * GameModel::GetSimulation() +{ + return sim; +} + +Renderer * GameModel::GetRenderer() +{ + return ren; +} + +void GameModel::SetPaused(bool pauseState) +{ + sim->sys_pause = pauseState?1:0; + notifyPausedChanged(); +} + +bool GameModel::GetPaused() +{ + return sim->sys_pause?true:false; +} + +void GameModel::notifyRendererChanged() +{ + for(int i = 0; i < observers.size(); i++) + { + observers[i]->NotifyRendererChanged(this); + } +} + +void GameModel::notifySimulationChanged() +{ + for(int i = 0; i < observers.size(); i++) + { + observers[i]->NotifySimulationChanged(this); + } +} + +void GameModel::notifyPausedChanged() +{ + for(int i = 0; i < observers.size(); i++) + { + observers[i]->NotifyPausedChanged(this); + } +} diff --git a/src/game/GameModel.h b/src/game/GameModel.h new file mode 100644 index 0000000..a2eb3ce --- /dev/null +++ b/src/game/GameModel.h @@ -0,0 +1,37 @@ +#ifndef GAMEMODEL_H +#define GAMEMODEL_H + +#include <vector> +#include "Simulation.h" +#include "Renderer.h" +#include "GameView.h" + +using namespace std; + +class GameView; +class Simulation; +class Renderer; + +class GameModel +{ +private: + vector<GameView*> observers; + Simulation * sim; + Renderer * ren; + int activeElement; + void notifyRendererChanged(); + void notifySimulationChanged(); + void notifyPausedChanged(); +public: + GameModel(); + void AddObserver(GameView * observer); + int GetActiveElement(); + void SetActiveElement(int element); + bool GetPaused(); + void SetPaused(bool pauseState); + + Simulation * GetSimulation(); + Renderer * GetRenderer(); +}; + +#endif // GAMEMODEL_H diff --git a/src/game/GameView.cpp b/src/game/GameView.cpp new file mode 100644 index 0000000..2576527 --- /dev/null +++ b/src/game/GameView.cpp @@ -0,0 +1,83 @@ +#include "Config.h" +#include "GameView.h" +#include "interface/Window.h" +#include "interface/Button.h" + +GameView::GameView(): + ui::Window(ui::Point(0, 0), ui::Point(XRES+BARSIZE, YRES+MENUSIZE)), + pointQueue(queue<ui::Point*>()), + isMouseDown(false), + ren(NULL) +{ + //Set up UI + class PauseAction : public ui::ButtonAction + { + GameView * v; + public: + PauseAction(GameView * _v) { v = _v; } + void ActionCallback(ui::Button * sender) + { + v->c->SetPaused(sender->GetToggleState()); + } + }; + pauseButton = new ui::Button(ui::Point(Size.X-18, Size.Y-18), ui::Point(16, 16), "\x90"); //Pause + pauseButton->SetTogglable(true); + pauseButton->SetActionCallback(new PauseAction(this)); + AddComponent(pauseButton); +} + +void GameView::NotifyRendererChanged(GameModel * sender) +{ + ren = sender->GetRenderer(); +} + +void GameView::NotifySimulationChanged(GameModel * sender) +{ + +} + +void GameView::NotifyPausedChanged(GameModel * sender) +{ + pauseButton->SetToggleState(sender->GetPaused()); +} + +void GameView::OnMouseMove(int x, int y, int dx, int dy) +{ + if(isMouseDown) + { + pointQueue.push(new ui::Point(x-dx, y-dy)); + pointQueue.push(new ui::Point(x, y)); + } +} + +void GameView::OnMouseDown(int x, int y, unsigned button) +{ + isMouseDown = true; + pointQueue.push(new ui::Point(x, y)); +} + +void GameView::OnMouseUp(int x, int y, unsigned button) +{ + if(isMouseDown) + { + isMouseDown = false; + pointQueue.push(new ui::Point(x, y)); + } +} + +void GameView::OnTick(float dt) +{ + if(!pointQueue.empty()) + { + c->DrawPoints(pointQueue); + } + c->Tick(); +} + +void GameView::OnDraw() +{ + if(ren) + { + ren->render_parts(); + } +} diff --git a/src/game/GameView.h b/src/game/GameView.h new file mode 100644 index 0000000..531a4b9 --- /dev/null +++ b/src/game/GameView.h @@ -0,0 +1,48 @@ +#ifndef GAMEVIEW_H +#define GAMEVIEW_H + +#include <queue> +#include "GameController.h" +#include "GameModel.h" +#include "interface/Window.h" +#include "interface/Point.h" +#include "interface/Button.h" + +using namespace std; + +class GameController; +class GameModel; +class GameView: public ui::Window +{ +private: + bool isMouseDown; + queue<ui::Point*> pointQueue; + GameController * c; + Renderer * ren; + //UI Elements + ui::Button * pauseButton; +public: + GameView(); + void AttachController(GameController * _c){ c = _c; } + void NotifyRendererChanged(GameModel * sender); + void NotifySimulationChanged(GameModel * sender); + void NotifyPausedChanged(GameModel * sender); + /*virtual void DoMouseMove(int x, int y, int dx, int dy); + virtual void DoMouseDown(int x, int y, unsigned button); + virtual void DoMouseUp(int x, int y, unsigned button); + //virtual void DoMouseWheel(int x, int y, int d); + //virtual void DoKeyPress(int key, bool shift, bool ctrl, bool alt); + //virtual void DoKeyRelease(int key, bool shift, bool ctrl, bool alt); + virtual void DoTick(float dt); + virtual void DoDraw();*/ + virtual void OnMouseMove(int x, int y, int dx, int dy); + virtual void OnMouseDown(int x, int y, unsigned button); + virtual void OnMouseUp(int x, int y, unsigned button); + //virtual void OnMouseWheel(int x, int y, int d) {} + //virtual void OnKeyPress(int key, bool shift, bool ctrl, bool alt) {} + //virtual void OnKeyRelease(int key, bool shift, bool ctrl, bool alt) {} + virtual void OnTick(float dt); + virtual void OnDraw(); +}; + +#endif // GAMEVIEW_H diff --git a/src/interface.old/Button.cpp b/src/interface.old/Button.cpp deleted file mode 100644 index a357c36..0000000 --- a/src/interface.old/Button.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Button.cpp - * - * Created on: Jan 8, 2012 - * Author: Simon - */ - -#include <iostream> - -#include "interface/Button.h" -#include "Graphics.h" - -namespace ui { - -Button::Button(int x, int y, int width, int height, const std::string& buttonText): - Component(x, y, width, height), - Toggleable(false), - ButtonText(buttonText), - isMouseInside(false), - isButtonDown(false), - state(false) -{ - -} - -void Button::Draw(void* userdata) -{ - Graphics * g = reinterpret_cast<Graphics*>(userdata); - //TODO: Cache text location, that way we don't have the text alignment code here - if(isButtonDown) - { - g->fillrect(X, Y, Width, Height, 255, 255, 255, 255); - g->drawtext(X+(Width-Graphics::textwidth((char *)ButtonText.c_str()))/2, Y+(Height-10)/2, ButtonText, 0, 0, 0, 255); - } - else - { - if(isMouseInside) - g->fillrect(X, Y, Width, Height, 20, 20, 20, 255); - g->drawrect(X, Y, Width, Height, 255, 255, 255, 255); - g->drawtext(X+(Width-Graphics::textwidth((char *)ButtonText.c_str()))/2, Y+(Height-10)/2, ButtonText, 255, 255, 255, 255); - } - /*sf::RenderWindow* rw = reinterpret_cast<sf::RenderWindow*>(userdata); //it better be a RenderWindow or so help your god - - //Draw component here - sf::Text textGraphic(ButtonText); - textGraphic.SetCharacterSize(11); - if(isButtonDown) - textGraphic.SetColor(sf::Color::Black); - else - textGraphic.SetColor(sf::Color::White); - sf::FloatRect tempRect = textGraphic.GetRect(); - textGraphic.SetPosition(ceil(X + Width/2 - tempRect.Width/2), ceil(Y + Height/2 - tempRect.Height/2)); - - if(isMouseInside) - { - if(isButtonDown) - rw->Draw(sf::Shape::Rectangle(X+2, Y+2, Width-4, Width-4, sf::Color::White, 2.f, sf::Color::Black)); - else - rw->Draw(sf::Shape::Rectangle(X+2, Y+2, Width-4, Width-4, sf::Color::Black, 2.f, sf::Color::White)); - } - else - { - if(isButtonDown) - rw->Draw(sf::Shape::Rectangle(X+2, Y+2, Width-4, Width-4, sf::Color::White, 2.f, sf::Color::Black)); - else - rw->Draw(sf::Shape::Rectangle(X+1, Y+1, Width-2, Width-2, sf::Color::Black, 1.f, sf::Color::White)); - } - - rw->Draw(textGraphic);*/ -} - -void Button::OnMouseUnclick(int x, int y, unsigned int button) -{ - if(button != 1) - { - return; //left click only! - } - - if(isButtonDown) - { - if(state) - { - state = false; - } - else - { - if(Toggleable) - { - state = true; - } - DoAction(); - } - } - - isButtonDown = false; -} - -void Button::OnMouseUp(int x, int y, unsigned int button) //mouse unclick is called before this -{ - if(button != 1) return; //left click only! - - isButtonDown = false; -} - -void Button::OnMouseClick(int x, int y, unsigned int button) -{ - if(button != 1) return; //left click only! - - isButtonDown = true; -} - -void Button::OnMouseEnter(int x, int y, int dx, int dy) -{ - isMouseInside = true; -} - -void Button::OnMouseLeave(int x, int y, int dx, int dy) -{ - isMouseInside = false; -} - -void Button::DoAction() -{ - std::cout << "Do action!"<<std::endl; -} - -} /* namespace ui */ diff --git a/src/interface.old/Component.cpp b/src/interface.old/Component.cpp deleted file mode 100644 index 48a329b..0000000 --- a/src/interface.old/Component.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Component.cpp - * - * Created on: Jan 8, 2012 - * Author: Simon - */ - -#include "interface/Component.h" - -namespace ui { - -Component::Component(int x, int y, int width, int height): - X(x), - Y(y), - Width(width), - Height(height), - Enabled(true), - Visible(true) -{ -} - -Component::~Component() -{ -} - -void Component::Draw(void* userdata) -{ -} - -void Component::Tick(float dt) -{ -} - -void Component::OnKeyPress(int key, bool shift, bool ctrl, bool alt) -{ -} - -void Component::OnKeyRelease(int key, bool shift, bool ctrl, bool alt) -{ -} - -void Component::OnMouseEnter(int localx, int localy, int dx, int dy) -{ -} - -void Component::OnMouseLeave(int localx, int localy, int dx, int dy) -{ -} - -void Component::OnMouseClick(int localx, int localy, unsigned int button) -{ -} - -void Component::OnMouseUnclick(int localx, int localy, unsigned int button) -{ -} - -void Component::OnMouseDown(int localx, int localy, unsigned int button) -{ -} - -void Component::OnMouseHover(int localx, int localy) -{ -} - -void Component::OnMouseMoved(int localx, int localy, int dx, int dy) -{ -} - -void Component::OnMouseMovedInside(int localx, int localy, int dx, int dy) -{ -} - -void Component::OnMouseUp(int localx, int localy, unsigned int button) -{ -} - -void Component::OnMouseWheel(int localx, int localy, int d) -{ -} - -void Component::OnMouseWheelInside(int localx, int localy, int d) -{ -} - -void Component::OnMouseWheelFocused(int localx, int localy, int d) -{ -} -} /* namespace ui */ diff --git a/src/interface.old/ControlFactory.cpp b/src/interface.old/ControlFactory.cpp deleted file mode 100644 index 300ceba..0000000 --- a/src/interface.old/ControlFactory.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "interface/ControlFactory.h" -#include "interface/Button.h" -#include "interface/Panel.h" -#include "interface/Window.h" - -ui::Panel * ControlFactory::MainMenu(GameSession * session, int x, int y, int width, int height) -{ - ui::Panel * mainMenu = new ui::Panel(x, y, width, height); - //mainMenu->Add(new ui::Button(0, 0, 20, 20, "Turd")); - return mainMenu; -} diff --git a/src/interface.old/Panel.cpp b/src/interface.old/Panel.cpp deleted file mode 100644 index 164bfa3..0000000 --- a/src/interface.old/Panel.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Panel.cpp - * - * Created on: Jan 8, 2012 - * Author: Simon - */ - -#include "interface/Panel.h" - -namespace ui { - -Panel::Panel(int x, int y, int width, int height): - Component(x, y, width, height) -{ - // TODO Auto-generated constructor stub - -} - -Panel::~Panel() { - // TODO Auto-generated destructor stub -} - -} /* namespace ui */ diff --git a/src/interface.old/Sandbox.cpp b/src/interface.old/Sandbox.cpp deleted file mode 100644 index 5e29bae..0000000 --- a/src/interface.old/Sandbox.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Sandbox.cpp - * - * Created on: Jan 8, 2012 - * Author: Simon - */ - -#include <iostream> - -#include "Config.h" - -#include "interface/Sandbox.h" -#include "interface/Component.h" -#include "Renderer.h" -#include "Simulation.h" - -namespace ui { - -Sandbox::Sandbox(): - Component(0, 0, XRES, YRES), - ren(NULL), - isMouseDown(false), - activeElement(1) -{ - sim = new Simulation(); -} - -Simulation * Sandbox::GetSimulation() -{ - return sim; -} - -void Sandbox::OnMouseMovedInside(int localx, int localy, int dx, int dy) -{ - if(isMouseDown) - { - sim->create_line(lastCoordX, lastCoordY, localx, localy, 2, 2, activeElement, 0); - lastCoordX = localx; - lastCoordY = localy; - } -} - -void Sandbox::OnMouseDown(int localx, int localy, unsigned int button) -{ - sim->create_line(localx, localy, localx, localy, 2, 2, activeElement, 0); - lastCoordX = localx; - lastCoordY = localy; - isMouseDown = true; -} - -void Sandbox::OnMouseUp(int localx, int localy, unsigned int button) -{ - sim->create_line(lastCoordX, lastCoordY, localx, localy, 2, 2, activeElement, 0); - lastCoordX = localx; - lastCoordY = localy; - isMouseDown = false; -} - -void Sandbox::Draw(void* userdata) -{ - Graphics * g = reinterpret_cast<Graphics*>(userdata); - if(!ren) - ren = new Renderer(g, sim); - ren->render_parts(); -} - -void Sandbox::Tick(float delta) -{ - sim->update_particles(); -} - -Sandbox::~Sandbox() { - // TODO Auto-generated destructor stub -} - -} /* namespace ui */ diff --git a/src/interface.old/State.cpp b/src/interface.old/State.cpp deleted file mode 100644 index 2828751..0000000 --- a/src/interface.old/State.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - * State.cpp - * - * Created on: Jan 8, 2012 - * Author: Simon - */ - -#include <vector> -#include <iostream> -#include <cstring> - -#include "interface/State.h" - -namespace ui { - -State::State(int w, int h): - mouseX(0), - mouseY(0), - mouseXP(0), - mouseYP(0), - width(w), - height(h), - Components() -{ -} - -State::~State() -{ - //Components.~vector(); // just in case // devnote : Nope.jpg Nate :3 -frankbro -} - -void State::Add(Component* child) -{ - Components.push_back(child); - child->Parent = this; -} - -void State::Remove(Component* child) -{ - for(int i = 0; i < Components.size(); i++) - if(Components[i] == child) - { - Components.erase(Components.begin() + i); - break; - } -} - -void State::Draw(void* userdata) -{ - //draw - for(int i = 0; i < Components.size(); i++) - { - if(Components[i]->Visible) - { - if(AllowExclusiveDrawing) - { - Components[i]->Draw(userdata); - } - else if( - Components[i]->X + Components[i]->Width >= 0 && - Components[i]->Y + Components[i]->Height >= 0 && - Components[i]->X < width && - Components[i]->Y < height ) - { - Components[i]->Draw(userdata); - } - } - } -} - -void State::Tick(float dt) -{ - //on mouse hover - for(int i = 0; i < Components.size(); i++) - if( mouseX >= Components[i]->X && - mouseY >= Components[i]->Y && - mouseX < Components[i]->X + Components[i]->Width && - mouseY < Components[i]->Y + Components[i]->Height ) - { - if(Components[i]->Enabled) - { - Components[i]->OnMouseHover(mouseX, mouseY); - } - break; - } - - //tick - for(int i = 0; i < Components.size(); i++) - Components[i]->Tick(dt); -} - -void State::OnKeyPress(int key, bool shift, bool ctrl, bool alt) -{ - //on key press - if(focusedComponent_ != NULL) - if(focusedComponent_->Enabled) - focusedComponent_->OnKeyPress(key, shift, ctrl, alt); -} - -void State::OnKeyRelease(int key, bool shift, bool ctrl, bool alt) -{ - //on key unpress - if(focusedComponent_ != NULL) - if(focusedComponent_->Enabled) - focusedComponent_->OnKeyRelease(key, shift, ctrl, alt); -} - -void State::OnMouseDown(int x, int y, unsigned int button) -{ - //on mouse click - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) - if(x >= Components[i]->X && y >= Components[i]->Y && x < Components[i]->X + Components[i]->Width && y < Components[i]->Y + Components[i]->Height) - { - Components[i]->OnMouseClick(x - Components[i]->X, y - Components[i]->Y, button); - this->focusedComponent_ = Components[i]; //set this component as the focused component - break; - } - - //on mouse down - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) - Components[i]->OnMouseDown(x - Components[i]->X, y - Components[i]->Y, button); -} - -void State::OnMouseMove(int x, int y) -{ - //update mouse coords - mouseX = x; - mouseY = y; - - //on mouse move (if true, and inside) - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) - { - int localX = x - Components[i]->X; - int localY = y - Components[i]->Y; - int localXP = mouseXP - Components[i]->X; - int localYP = mouseYP - Components[i]->Y; - int dx = x - mouseXP; - int dy = x - mouseYP; - - Components[i]->OnMouseMoved(localX, localY, dx, dy); - - //is the mouse inside - if(localX >= 0 && - localY >= 0 && - localX < Components[i]->Width && - localY < Components[i]->Height ) - { - //was the mouse outside last tick? - if(localXP < 0 || - localXP >= Components[i]->Width || - localYP < 0 || - localYP >= Components[i]->Height ) - { - Components[i]->OnMouseEnter(localX, localY, dx, dy); - } - - Components[i]->OnMouseMovedInside(localX, localY, dx, dy); - - break; //found the top-most component under mouse, break that shit - } - //not inside, let's see if it used to be inside last tick - else if (localXP >= 0 && - localYP >= 0 && - localXP < Components[i]->Width && - localYP < Components[i]->Height ) - { - Components[i]->OnMouseLeave(localX, localY, x - mouseXP, y - mouseYP); - } - } - else //is locked - { - int localX = x - Components[i]->X; - int localY = y - Components[i]->Y; - - //is the mouse inside - if(localX >= 0 && - localY >= 0 && - localX < Components[i]->Width && - localY < Components[i]->Height ) - { - break; //it's the top-most component under the mouse, we don't want to go under it. - } - } - // end of for loop here - - //set the previous mouse coords - mouseXP = x; - mouseYP = y; -} - -void State::OnMouseUp(int x, int y, unsigned int button) -{ - //on mouse unclick - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) - if(x >= Components[i]->X && y >= Components[i]->Y && x < Components[i]->X + Components[i]->Width && y < Components[i]->Y + Components[i]->Height) - { - Components[i]->OnMouseUnclick(x - Components[i]->X, y - Components[i]->Y, button); - break; - } - - //on mouse up - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) - Components[i]->OnMouseUp(x - Components[i]->X, y - Components[i]->Y, button); -} - -void State::OnMouseWheel(int x, int y, int d) -{ - //focused mouse wheel - if(focusedComponent_ != NULL) - focusedComponent_->OnMouseWheelFocused(x - focusedComponent_->X, y - focusedComponent_->Y, d); - - //mouse wheel inside - for(int i = Components.size() - 1; i > -1 ; i--) - if(x >= Components[i]->X && y >= Components[i]->Y && x < Components[i]->X + Components[i]->Width && y < Components[i]->Y + Components[i]->Height) - { - if(Components[i]->Enabled) - Components[i]->OnMouseWheelInside(x - Components[i]->X, y - Components[i]->Y, d); - break; //found top-most component under mouse - } - - //on mouse wheel - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) - Components[i]->OnMouseWheel(x - Components[i]->X, y - Components[i]->Y, d); -} - - -} /* namespace ui */ diff --git a/src/interface.old/Window.cpp b/src/interface.old/Window.cpp deleted file mode 100644 index 624bf9a..0000000 --- a/src/interface.old/Window.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Window.cpp - * - * Created on: Jan 8, 2012 - * Author: Simon - */ - -#include "interface/Window.h" - -namespace ui { - -Window::Window(): - State(width, height) -{ - // TODO Auto-generated constructor stub - -} - -Window::~Window() { - // TODO Auto-generated destructor stub -} - -} /* namespace ui */ diff --git a/src/interface/Button.cpp b/src/interface/Button.cpp index 6ea9854..a3f76b9 100644 --- a/src/interface/Button.cpp +++ b/src/interface/Button.cpp @@ -10,15 +10,17 @@ #include "interface/Button.h" #include "Graphics.h" #include "Global.h" +#include "Engine.h" namespace ui { -Button::Button(State* parent_state, std::string buttonText): +Button::Button(Window* parent_state, std::string buttonText): Component(parent_state), ButtonText(buttonText), isMouseInside(false), isButtonDown(false), - isTogglable(false) + isTogglable(false), + actionCallback(NULL) { } @@ -28,7 +30,8 @@ Button::Button(Point position, Point size, std::string buttonText): ButtonText(buttonText), isMouseInside(false), isButtonDown(false), - isTogglable(false) + isTogglable(false), + actionCallback(NULL) { } @@ -38,7 +41,8 @@ Button::Button(std::string buttonText): ButtonText(buttonText), isMouseInside(false), isButtonDown(false), - isTogglable(false) + isTogglable(false), + actionCallback(NULL) { } @@ -68,13 +72,13 @@ inline void Button::SetToggleState(bool state) void Button::Draw(const Point& screenPos) { - Graphics * g = Global::Ref().g; + Graphics * g = ui::Engine::Ref().g; Point Position = screenPos; // = reinterpret_cast<Graphics*>(userdata); //TODO: Cache text location, that way we don't have the text alignment code here if(isButtonDown || (isTogglable && toggle)) { - g->fillrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255); + g->fillrect(Position.X-1, Position.Y-1, Size.X+2, Size.Y+2, 255, 255, 255, 255); g->drawtext(Position.X+(Size.X-Graphics::textwidth((char *)ButtonText.c_str()))/2, Position.Y+(Size.Y-10)/2, ButtonText, 0, 0, 0, 255); } else @@ -116,7 +120,6 @@ void Button::Draw(const Point& screenPos) void Button::OnMouseUnclick(int x, int y, unsigned int button) { - std::cout << "Unclick!" << std::endl; if(button != 1) { return; //left click only! @@ -160,6 +163,15 @@ void Button::OnMouseLeave(int x, int y) void Button::DoAction() { std::cout << "Do action!"<<std::endl; + //if(actionCallback) + // (*(actionCallback))(); + if(actionCallback) + actionCallback->ActionCallback(this); +} + +void Button::SetActionCallback(ButtonAction * action) +{ + actionCallback = action; } Button::~Button() diff --git a/src/interface/Button.h b/src/interface/Button.h new file mode 100644 index 0000000..5f2d71f --- /dev/null +++ b/src/interface/Button.h @@ -0,0 +1,60 @@ +/* + * Button.h + * + * Created on: Jan 8, 2012 + * Author: Simon + */ + +#ifndef BUTTON_H_ +#define BUTTON_H_ + +#include <string> + +#include "Component.h" + +namespace ui +{ +class Button; +class ButtonAction +{ +public: + virtual void ActionCallback(ui::Button * sender) {} +}; + +class Button : public Component +{ +public: + Button(Window* parent_state, std::string buttonText); + + Button(Point position, Point size, std::string buttonText); + + Button(std::string buttonText); + virtual ~Button(); + + bool Toggleable; + + std::string ButtonText; + + virtual void OnMouseClick(int x, int y, unsigned int button); + virtual void OnMouseUnclick(int x, int y, unsigned int button); + //virtual void OnMouseUp(int x, int y, unsigned int button); + + virtual void OnMouseEnter(int x, int y); + virtual void OnMouseLeave(int x, int y); + + virtual void Draw(const Point& screenPos); + + inline bool GetState() { return state; } + virtual void DoAction(); //action of button what ever it may be + void SetTogglable(bool isTogglable); + bool GetTogglable(); + inline bool GetToggleState(); + inline void SetToggleState(bool state); + void SetActionCallback(ButtonAction * action); + +protected: + bool isButtonDown, state, isMouseInside, isTogglable, toggle; + ButtonAction * actionCallback; +}; +} +#endif /* BUTTON_H_ */ diff --git a/src/interface/Component.cpp b/src/interface/Component.cpp index 49ff7f8..75e9c40 100644 --- a/src/interface/Component.cpp +++ b/src/interface/Component.cpp @@ -2,12 +2,12 @@ #include "interface/Component.h" #include "interface/Engine.h" #include "interface/Point.h" -#include "interface/State.h" +#include "interface/Window.h" #include "interface/Panel.h" using namespace ui; -Component::Component(State* parent_state): +Component::Component(Window* parent_state): parentstate_(parent_state), _parent(NULL), Position(Point(0,0)), @@ -45,9 +45,9 @@ bool Component::IsFocused() const return parentstate_->IsFocused(this); } -void Component::SetParentState(State* state) +void Component::SetParentWindow(Window* window) { - parentstate_ = state; + parentstate_ = window; } void Component::SetParent(Panel* new_parent) @@ -65,7 +65,7 @@ void Component::SetParent(Panel* new_parent) _parent->RemoveChild(i, false); // add ourself to the parent state - GetParentState()->AddComponent(this); + GetParentWindow()->AddComponent(this); //done in this loop. break; @@ -76,8 +76,8 @@ void Component::SetParent(Panel* new_parent) else { // remove from parent state (if in parent state) and place in new parent - if(GetParentState()) - GetParentState()->RemoveComponent(this); + if(GetParentWindow()) + GetParentWindow()->RemoveComponent(this); new_parent->children.push_back(this); } this->_parent = new_parent; diff --git a/src/interface/Component.h b/src/interface/Component.h new file mode 100644 index 0000000..578aba6 --- /dev/null +++ b/src/interface/Component.h @@ -0,0 +1,204 @@ +#pragma once + +#include "Point.h" +#include "Window.h" +#include "Platform.h" + +namespace ui +{ + class Window; + class Panel; + + /* class Component + * + * An interactive UI component that can be added to a state or an XComponent*. + * *See sys::XComponent + */ + class Component + { + public: + Component(Window* parent_state); + Component(Point position, Point size); + Component(); + virtual ~Component(); + + void* UserData; + inline Window* const GetParentWindow() const { return parentstate_; } + bool IsFocused() const; + + Point Position; + Point Size; + bool Locked; + bool Visible; + + /* See the parent of this component. + * If new_parent is NULL, this component will have no parent. (THIS DOES NOT delete THE COMPONENT. See XComponent::RemoveChild) + */ + void SetParentWindow(Window* window); + void SetParent(Panel* new_parent); + + //Get the parent component. + inline Panel* const GetParent() const { return _parent; } + + //UI functions: + /* + void Tick(float dt); + void Draw(const Point& screenPos); + + void OnMouseHover(int localx, int localy); + void OnMouseMoved(int localx, int localy, int dx, int dy); + void OnMouseMovedInside(int localx, int localy, int dx, int dy); + void OnMouseEnter(int localx, int localy); + void OnMouseLeave(int localx, int localy); + void OnMouseDown(int x, int y, unsigned int button); + void OnMouseUp(int x, int y, unsigned int button); + void OnMouseClick(int localx, int localy, unsigned int button); + void OnMouseUnclick(int localx, int localy, unsigned int button); + void OnMouseWheel(int localx, int localy, int d); + void OnMouseWheelInside(int localx, int localy, int d); + void OnKeyPress(int key, bool shift, bool ctrl, bool alt); + void OnKeyRelease(int key, bool shift, bool ctrl, bool alt); + */ + + /// + // Called: Every tick. + // Params: + // dt: The change in time. + /// + virtual void Tick(float dt); + + /// + // Called: When ready to draw. + // Params: + // None + /// + virtual void Draw(const Point& screenPos); + + + + + /// + // Called: When the mouse is currently hovering over the item. (Called every tick) + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + /// + virtual void OnMouseHover(int localx, int localy); + + /// + // Called: When the mouse moves. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + // dx: Mouse X delta. + // dy: Mouse Y delta. + /// + virtual void OnMouseMoved(int localx, int localy, int dx, int dy); + + /// + // Called: When the mouse moves. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + // dx: Mouse X delta. + // dy: Mouse Y delta. + /// + virtual void OnMouseMovedInside(int localx, int localy, int dx, int dy); + + /// + // Called: When the mouse moves on top of the item. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + // dx: Mouse X delta. + // dy: Mouse Y delta. + /// + virtual void OnMouseEnter(int localx, int localy); + + /// + // Called: When the mouse leaves the item. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + /// + virtual void OnMouseLeave(int localx, int localy); + + /// + // Called: When a mouse button is pressed. + // Params: + // x: X position of the mouse. + // y: Y position of the mouse. + // button: The button that is being held down. + /// + virtual void OnMouseDown(int x, int y, unsigned button); + + /// + // Called: When a mouse button is released. + // Params: + // x: X position of the mouse. + // y: Y position of the mouse. + // button: The button that is being released. + /// + virtual void OnMouseUp(int x, int y, unsigned button); + + /// + // Called: When a mouse button is pressed on top of the item. + // Params: + // x: X position of the mouse. + // y: Y position of the mouse. + // button: The button that is being held down. + /// + virtual void OnMouseClick(int localx, int localy, unsigned button); + + /// + // Called: When a mouse button is released on top of the item. + // Params: + // x: X position of the mouse. + // y: Y position of the mouse. + // button: The button that is being released. + /// + virtual void OnMouseUnclick(int localx, int localy, unsigned button); + + /// + // Called: When the mouse wheel moves/changes. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + // d: The mouse wheel movement value. + /// + virtual void OnMouseWheel(int localx, int localy, int d); + + /// + // Called: When the mouse wheel moves/changes on top of the item. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + // d: The mouse wheel movement value. + /// + virtual void OnMouseWheelInside(int localx, int localy, int d); + + /// + // Called: When a key is pressed. + // Params: + // key: The value of the key that is being pressed. + // shift: Shift key is down. + // ctrl: Control key is down. + // alt: Alternate key is down. + /// + virtual void OnKeyPress(int key, bool shift, bool ctrl, bool alt); + + /// + // Called: When a key is released. + // Params: + // key: The value of the key that is being released. + // shift: Shift key is released. + // ctrl: Control key is released. + // alt: Alternate key is released. + /// + virtual void OnKeyRelease(int key, bool shift, bool ctrl, bool alt); + + private: + Window* parentstate_; + Panel* _parent; + }; +} diff --git a/src/interface/ControlFactory.cpp b/src/interface/ControlFactory.cpp index 372ed31..7132499 100644 --- a/src/interface/ControlFactory.cpp +++ b/src/interface/ControlFactory.cpp @@ -50,10 +50,5 @@ ui::Panel * ControlFactory::MainMenu(int x, int y, int width, int height) mainMenu->AddChild(tempButton); //Render options currentX += 18; - tempButton = new ui::Button(ui::Point(currentX, 1), ui::Point(16, height-2), "\x90"); //Pause - tempButton->SetTogglable(true); - mainMenu->AddChild(tempButton); - currentX += 18; - return mainMenu; } diff --git a/src/interface/ControlFactory.h b/src/interface/ControlFactory.h new file mode 100644 index 0000000..0f8ad61 --- /dev/null +++ b/src/interface/ControlFactory.h @@ -0,0 +1,14 @@ +#ifndef CONTROLFACTORY_H +#define CONTROLFACTORY_H + +#include "Panel.h" +#include "Engine.h" + +class ControlFactory +{ +public: + static ui::Panel * MainMenu(int x, int y, int width, int height); + +}; + +#endif // CONTROLFACTORY_H diff --git a/src/interface/Engine.cpp b/src/interface/Engine.cpp index 25f2038..55a2370 100644 --- a/src/interface/Engine.cpp +++ b/src/interface/Engine.cpp @@ -1,22 +1,25 @@ #include <iostream> #include "Config.h" +#include <stack> + #include "Global.h" +#include "interface/Window.h" #include "interface/Platform.h" #include "interface/Engine.h" -#include "interface/State.h" #include "Graphics.h" using namespace ui; +using namespace std; Engine::Engine(): state_(NULL), - statequeued_(NULL), mousex_(0), mousey_(0), mousexp_(0), mouseyp_(0), - FpsLimit(60.0f) + FpsLimit(60.0f), + windows(stack<Window*>()) { } @@ -40,7 +43,30 @@ void Engine::Exit() running_ = false; } -void Engine::SetState(State * state) +void Engine::ShowWindow(Window * window) +{ + if(state_) + { + windows.push(window); + } + state_ = window; + windows.push(window); +} + +void Engine::CloseWindow() +{ + if(!windows.empty()) + { + state_ = windows.top(); + windows.pop(); + } + else + { + state_ = NULL; + } +} + +/*void Engine::SetState(State * state) { if(state_) //queue if currently in a state statequeued_ = state; @@ -50,7 +76,7 @@ void Engine::SetState(State * state) if(state_) state_->DoInitialized(); } -} +}*/ void Engine::SetSize(int width, int height) { @@ -63,7 +89,7 @@ void Engine::Tick(float dt) if(state_ != NULL) state_->DoTick(dt); - if(statequeued_ != NULL) + /*if(statequeued_ != NULL) { if(state_ != NULL) { @@ -76,15 +102,15 @@ void Engine::Tick(float dt) if(state_ != NULL) state_->DoInitialized(); - } + }*/ } void Engine::Draw() { if(state_) state_->DoDraw(); - Global::Ref().g->Blit(); - Global::Ref().g->Clear(); + g->Blit(); + g->Clear(); } void Engine::onKeyPress(int key, bool shift, bool ctrl, bool alt) diff --git a/src/interface/Engine.h b/src/interface/Engine.h new file mode 100644 index 0000000..7bf78f9 --- /dev/null +++ b/src/interface/Engine.h @@ -0,0 +1,71 @@ +#pragma once + +#include <stack> +#include <SDL/SDL.h> +#include "Singleton.h" +#include "Platform.h" +#include "Graphics.h" +#include "Window.h" + +namespace ui +{ + class Window; + + /* class Engine + * + * Controls the User Interface. + * Send user inputs to the Engine and the appropriate controls and components will interact. + */ + class Engine: public Singleton<Engine> + { + public: + Engine(); + ~Engine(); + + void ShowWindow(Window * window); + void CloseWindow(); + + void onMouseMove(int x, int y); + void onMouseClick(int x, int y, unsigned button); + void onMouseUnclick(int x, int y, unsigned button); + void onMouseWheel(int x, int y, int delta); + void onKeyPress(int key, bool shift, bool ctrl, bool alt); + void onKeyRelease(int key, bool shift, bool ctrl, bool alt); + void onResize(int newWidth, int newHeight); + void onClose(); + + void Begin(int width, int height); + inline bool Running() { return running_; } + void Exit(); + + void Tick(float dt); + void Draw(); + + inline int GetMouseX() { return mousex_; } + inline int GetMouseY() { return mousey_; } + inline int GetWidth() { return width_; } + inline int GetHeight() { return height_; } + + inline void SetSize(int width, int height); + + //void SetState(Window* state); + //inline State* GetState() { return state_; } + inline Window* GetWindow() { return state_; } + float FpsLimit; + Graphics * g; + private: + std::stack<Window*> windows; + //Window* statequeued_; + Window* state_; + + bool running_; + + int mousex_; + int mousey_; + int mousexp_; + int mouseyp_; + int width_; + int height_; + }; + +} diff --git a/src/interface/Label.cpp b/src/interface/Label.cpp index c77b6bf..cf09d4e 100644 --- a/src/interface/Label.cpp +++ b/src/interface/Label.cpp @@ -6,7 +6,7 @@ using namespace ui; -Label::Label(State* parent_state, std::string labelText): +Label::Label(Window* parent_state, std::string labelText): Component(parent_state), LabelText(labelText) { @@ -35,6 +35,6 @@ Label::~Label() void Label::Draw(const Point& screenPos) { - Graphics * g = Global::Ref().g; + Graphics * g = Engine::Ref().g; g->drawtext(Position.X+(Size.X-Graphics::textwidth((char *)LabelText.c_str()))/2, Position.Y+(Size.Y-10)/2, LabelText, 255, 255, 255, 255); } diff --git a/src/interface/Label.h b/src/interface/Label.h new file mode 100644 index 0000000..e56852e --- /dev/null +++ b/src/interface/Label.h @@ -0,0 +1,26 @@ +#ifndef LABEL_H +#define LABEL_H + +#include <string> + +#include "Component.h" + +namespace ui +{ + class Label : public Component + { + public: + Label(Window* parent_state, std::string labelText); + + Label(Point position, Point size, std::string labelText); + + Label(std::string labelText); + virtual ~Label(); + + std::string LabelText; + + virtual void Draw(const Point& screenPos); + }; +} + +#endif // LABEL_H diff --git a/src/interface/Panel.cpp b/src/interface/Panel.cpp index e44663a..acfcf53 100644 --- a/src/interface/Panel.cpp +++ b/src/interface/Panel.cpp @@ -5,12 +5,12 @@ #include "interface/Panel.h" #include "interface/Point.h" -#include "interface/State.h" +#include "interface/Window.h" #include "interface/Component.h" using namespace ui; -Panel::Panel(State* parent_state): +Panel::Panel(Window* parent_state): Component(parent_state) { @@ -84,7 +84,7 @@ void Panel::Draw(const Point& screenPos) // the component must be visible if(children[i]->Visible) { - if(GetParentState()->AllowExclusiveDrawing) + if(GetParentWindow()->AllowExclusiveDrawing) { //who cares if the component is off the screen? draw anyway. Point scrpos = screenPos + children[i]->Position; @@ -143,7 +143,7 @@ void Panel::OnMouseClick(int localx, int localy, unsigned button) localy < children[i]->Position.Y + children[i]->Size.Y ) { childclicked = true; - GetParentState()->FocusComponent(children[i]); + GetParentWindow()->FocusComponent(children[i]); children[i]->OnMouseClick(localx - children[i]->Position.X, localy - children[i]->Position.Y, button); break; } @@ -154,7 +154,7 @@ void Panel::OnMouseClick(int localx, int localy, unsigned button) if(!childclicked) { XOnMouseClick(localx, localy, button); - GetParentState()->FocusComponent(this); + GetParentWindow()->FocusComponent(this); } } diff --git a/src/interface/Panel.h b/src/interface/Panel.h new file mode 100644 index 0000000..51f52aa --- /dev/null +++ b/src/interface/Panel.h @@ -0,0 +1,136 @@ +#pragma once +#include <vector> +//#include "Platform.h" + +#include "interface/Point.h" +#include "interface/Window.h" +#include "interface/Component.h" + +namespace ui +{ + /* class XComponent + * + * An eXtension of the Component class. + * Adds the ability to have child components. + * + * See sys::Component + */ +class Component; + class Panel : public Component + { + public: + friend class Component; + + Panel(Window* parent_state); + Panel(Point position, Point size); + Panel(); + virtual ~Panel(); + + /* Add a child component. + * Similar to XComponent::SetParent + * + * If the component is already parented, then this will become the new parent. + */ + void AddChild(Component* c); + + // Remove child from component. This DOES NOT free the component from memory. + void RemoveChild(Component* c); + + // Remove child from component. This WILL free the component from memory unless told otherwise. + void RemoveChild(unsigned idx, bool freeMem = true); + + //Grab the number of children this component owns. + int GetChildCount(); + + //Get child of this component by index. + Component* GetChild(unsigned idx); + + void Tick(float dt); + void Draw(const Point& screenPos); + + void OnMouseHover(int localx, int localy); + void OnMouseMoved(int localx, int localy, int dx, int dy); + void OnMouseMovedInside(int localx, int localy, int dx, int dy); + void OnMouseEnter(int localx, int localy); + void OnMouseLeave(int localx, int localy); + void OnMouseDown(int x, int y, unsigned button); + void OnMouseUp(int x, int y, unsigned button); + void OnMouseClick(int localx, int localy, unsigned button); + void OnMouseUnclick(int localx, int localy, unsigned button); + void OnMouseWheel(int localx, int localy, int d); + void OnMouseWheelInside(int localx, int localy, int d); + void OnKeyPress(int key, bool shift, bool ctrl, bool alt); + void OnKeyRelease(int key, bool shift, bool ctrl, bool alt); + + protected: + // child components + std::vector<ui::Component*> children; + + //UI functions: + /* + void XTick(float dt); + void XDraw(const Point& screenPos); + + void XOnMouseHover(int localx, int localy); + void XOnMouseMoved(int localx, int localy, int dx, int dy); + void XOnMouseMovedInside(int localx, int localy, int dx, int dy); + void XOnMouseEnter(int localx, int localy); + void XOnMouseLeave(int localx, int localy); + void XOnMouseDown(int x, int y, unsigned int button); + void XOnMouseUp(int x, int y, unsigned int button); + void XOnMouseClick(int localx, int localy, unsigned int button); + void XOnMouseUnclick(int localx, int localy, unsigned int button); + void XOnMouseWheel(int localx, int localy, int d); + void XOnMouseWheelInside(int localx, int localy, int d); + void XOnKeyPress(int key, bool shift, bool ctrl, bool alt); + void XOnKeyRelease(int key, bool shift, bool ctrl, bool alt); + */ + + // Overridable. Called by XComponent::Tick() + virtual void XTick(float dt); + + // Overridable. Called by XComponent::Draw() + virtual void XDraw(const Point& screenPos); + + + // Overridable. Called by XComponent::XOnMouseHover() + virtual void XOnMouseHover(int localx, int localy); + + // Overridable. Called by XComponent::OnMouseMoved() + virtual void XOnMouseMoved(int localx, int localy, int dx, int dy); + + // Overridable. Called by XComponent::OnMouseMovedInside() + virtual void XOnMouseMovedInside(int localx, int localy, int dx, int dy); + + // Overridable. Called by XComponent::OnMouseEnter() + virtual void XOnMouseEnter(int localx, int localy); + + // Overridable. Called by XComponent::OnMouseLeave() + virtual void XOnMouseLeave(int localx, int localy); + + // Overridable. Called by XComponent::OnMouseDown() + virtual void XOnMouseDown(int x, int y, unsigned button); + + // Overridable. Called by XComponent::OnMouseUp() + virtual void XOnMouseUp(int x, int y, unsigned button); + + // Overridable. Called by XComponent::OnMouseClick() + virtual void XOnMouseClick(int localx, int localy, unsigned button); + + // Overridable. Called by XComponent::OnMouseUnclick() + virtual void XOnMouseUnclick(int localx, int localy, unsigned button); + + // Overridable. Called by XComponent::OnMouseWheel() + virtual void XOnMouseWheel(int localx, int localy, int d); + + // Overridable. Called by XComponent::OnMouseWheelInside() + virtual void XOnMouseWheelInside(int localx, int localy, int d); + + // Overridable. Called by XComponent::OnKeyPress() + virtual void XOnKeyPress(int key, bool shift, bool ctrl, bool alt); + + // Overridable. Called by XComponent::OnKeyRelease() + virtual void XOnKeyRelease(int key, bool shift, bool ctrl, bool alt); + }; + +} diff --git a/src/interface/Platform.h b/src/interface/Platform.h new file mode 100644 index 0000000..c57dca6 --- /dev/null +++ b/src/interface/Platform.h @@ -0,0 +1,108 @@ +#pragma once + + +/* ***** Platform-ness ***** */ + +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32_LEAN_AND_MEAN) +# define IEF_PLATFORM_WIN32 +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +#elif defined(linux) || defined(_linux) || defined(__linux) +# define IEF_PLATFORM_LINUX + +#elif defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh) +# define IEF_PLATFORM_MACOSX + +//#elif defined(__FreeBSD__) || define(__FreeBSD_kernel__) +//# define IEF_PLATFORM_FREEBSD + +#else +# error Operating System not supported. +#endif + + +/* ***** Endian-ness ***** */ + +#if defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || (defined(__MIPS__) && defined(__MISPEB__)) || defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || defined(__sparc__) || defined(__hppa__) +# define IEF_ENDIAN_BIG + +#else +# define IEF_ENDIAN_LITTLE +#endif + + +/* ***** Debug-ness ***** */ + +#if !defined(NDEBUG) || defined(_DEBUG) +# define IEF_DEBUG +#endif + + +/* ***** Primitive Types ***** */ + +#ifndef NULL +# define NULL 0 +#endif + +#include <climits> +namespace sys +{ + +#if UCHAR_MAX == 0xFF //char + typedef signed char s8; + typedef unsigned char u8; +#else +# error No 8-Bit Integer supported. +#endif +#if USHRT_MAX == 0xFFFF //short + typedef signed short s16; + typedef unsigned short u16; +#elif UINT_MAX == 0xFFFF + typedef signed int s16; + typedef unsigned int u16; +#elif ULONG_MAX == 0xFFFF + typedef signed long s16; + typedef unsigned long u16; + #else + # error No 16-Bit Integer supported. + #endif + #if USHRT_MAX == 0xFFFFFFFF //int + typedef signed short s32; + typedef unsigned short u32; +#elif UINT_MAX == 0xFFFFFFFF + typedef signed int s32; + typedef unsigned int u32; +#elif ULONG_MAX == 0xFFFFFFFF + typedef signed long s32; + typedef unsigned long u32; + #else + # error No 32-Bit Integer supported. + #endif +#if UINT_MAX == 0xFFFFFFFFFFFFFFFF //long + typedef signed int s64; + typedef unsigned int u64; +#elif ULONG_MAX == 0xFFFFFFFFFFFFFFFF + typedef signed long s64; + typedef unsigned long u64; +#elif ULLONG_MAX == 0xFFFFFFFFFFFFFFFF + typedef signed long long s64; + typedef unsigned long long u64; +#else +# pragma message("Warning: 64-bit not supported. s64 and u64 defined as 32-bit.") + typedef s32 s64; + typedef u32 u64; +#endif +//floating +typedef float f32; +typedef double f64; +//misc +typedef u8 byte; +typedef u8 ubyte; +typedef s8 sbyte; +typedef s64 llong; +typedef s64 sllong; +typedef u64 ullong; +typedef char* cstring; + +} //namespace sys diff --git a/src/interface/Point.h b/src/interface/Point.h new file mode 100644 index 0000000..0d0250c --- /dev/null +++ b/src/interface/Point.h @@ -0,0 +1,136 @@ +#pragma once +#include "Platform.h" + +namespace ui +{ + +//Lightweight 2D Int32/Float32 Point struct for UI +struct Point +{ +#if ENABLE_FLOAT_UI +# define POINT_T float +#else +# define POINT_T int +#endif + + POINT_T X; + POINT_T Y; + + Point(POINT_T x, POINT_T y) + : X(x) + , Y(y) + { + } + + inline Point operator - () const + { + return Point(-X, -Y); + } + + inline Point operator + (const Point& v) const + { + return Point(X + v.X, Y + v.Y); + } + + inline Point operator - (const Point& v) const + { + return Point(X - v.X, Y - v.Y); + } + + inline Point operator * (const Point& v) const + { + return Point(X * v.X, Y * v.Y); + } + + inline Point operator * (int v) const + { + return Point(X * static_cast<POINT_T>(v), Y * static_cast<POINT_T>(v)); + } + + inline Point operator * (float v) const + { + return Point(X * static_cast<POINT_T>(v), Y * static_cast<POINT_T>(v)); + } + + inline Point operator / (const Point& v) const + { + return Point(X / v.X, Y / v.Y); + } + + inline Point operator / (int v) const + { + return Point(X / static_cast<POINT_T>(v), Y / static_cast<POINT_T>(v)); + } + + inline Point operator / (float v) const + { + return Point(X / static_cast<POINT_T>(v), Y / static_cast<POINT_T>(v)); + } + + inline void operator += (const Point& v) + { + X += v.X; + Y += v.Y; + } + + inline void operator -= (const Point& v) + { + X -= v.X; + Y -= v.Y; + } + + inline void operator *= (const Point& v) + { + X *= v.X; + Y *= v.Y; + } + + inline void operator *= (int v) + { + X *= static_cast<POINT_T>(v); + Y *= static_cast<POINT_T>(v); + } + + inline void operator *= (float v) + { + X *= static_cast<POINT_T>(v); + Y *= static_cast<POINT_T>(v); + } + + inline void operator /= (const Point& v) + { + X /= v.X; + Y /= v.Y; + } + + inline void operator /= (int v) + { + X /= static_cast<POINT_T>(v); + Y /= static_cast<POINT_T>(v); + } + + inline void operator /= (float v) + { + X /= static_cast<POINT_T>(v); + Y /= static_cast<POINT_T>(v); + } + + inline bool operator == (const Point& v) const + { + return (X == v.X && Y == v.Y); + } + + inline bool operator != (const Point& v) const + { + return (X != v.X || Y != v.Y); + } + + inline void operator = (const Point& v) + { + X = v.X; + Y = v.Y; + } + +}; + +} diff --git a/src/interface/Sandbox.cpp b/src/interface/Sandbox.cpp index a9760e7..9a858f8 100644 --- a/src/interface/Sandbox.cpp +++ b/src/interface/Sandbox.cpp @@ -16,6 +16,7 @@ #include "interface/Component.h" #include "Renderer.h" #include "Simulation.h" +#include "Engine.h" namespace ui { @@ -60,7 +61,7 @@ void Sandbox::OnMouseUp(int localx, int localy, unsigned int button) void Sandbox::Draw(const Point& screenPos) { - Graphics * g = Global::Ref().g; + Graphics * g = Engine::Ref().g; if(!ren) ren = new Renderer(g, sim); ren->render_parts(); diff --git a/src/interface/Sandbox.h b/src/interface/Sandbox.h new file mode 100644 index 0000000..fb4a668 --- /dev/null +++ b/src/interface/Sandbox.h @@ -0,0 +1,39 @@ +/* + * Sandbox.h + * + * Created on: Jan 8, 2012 + * Author: Simon + */ + +#ifndef SANDBOX_H_ +#define SANDBOX_H_ + +#include <queue> +#include "Point.h" +#include "Component.h" +#include "Simulation.h" +#include "Renderer.h" + +namespace ui { + +class Sandbox: public ui::Component { +private: + int lastCoordX, lastCoordY; + int activeElement; + std::queue<Point*> pointQueue; + bool isMouseDown; + Renderer * ren; + Simulation * sim; +public: + Sandbox(); + virtual Simulation * GetSimulation(); + virtual void OnMouseMoved(int localx, int localy, int dx, int dy); + virtual void OnMouseClick(int localx, int localy, unsigned int button); + virtual void OnMouseUp(int localx, int localy, unsigned int button); + virtual void Draw(const Point& screenPos); + virtual void Tick(float delta); + virtual ~Sandbox(); +}; + +} /* namespace ui */ +#endif /* SANDBOX_H_ */ diff --git a/src/interface/State.cpp b/src/interface/Window.cpp index 665e2e8..e28d34b 100644 --- a/src/interface/State.cpp +++ b/src/interface/Window.cpp @@ -1,30 +1,29 @@ -#include <vector> -#include "interface/Component.h" -#include "interface/Engine.h" -#include "interface/State.h" -//#include "Platform.h" +#include "Window.h" +#include "Component.h" +#include "interface/Point.h" using namespace ui; -State::State() -: UserData(NULL) -, focusedComponent_(NULL) +Window::Window(Point _position, Point _size): + Position(_position), + Size(_size), + focusedComponent_(NULL) { } -State::~State() +Window::~Window() { for(unsigned i = 0, sz = Components.size(); i < sz; ++i) if( Components[i] ) delete Components[i]; } -void State::AddComponent(Component* c) +void Window::AddComponent(Component* c) { // TODO: do a check if component was already added? - if(c->GetParentState()==NULL) + if(c->GetParentWindow()==NULL) { - c->SetParentState(this); + c->SetParentWindow(this); Components.push_back(c); } else @@ -33,17 +32,17 @@ void State::AddComponent(Component* c) } } -unsigned State::GetComponentCount() +unsigned Window::GetComponentCount() { return Components.size(); } -Component* State::GetComponent(unsigned idx) +Component* Window::GetComponent(unsigned idx) { return Components[idx]; } -void State::RemoveComponent(Component* c) +void Window::RemoveComponent(Component* c) { // remove component WITHOUT freeing it. for(unsigned i = 0; i < Components.size(); ++i) @@ -52,43 +51,43 @@ void State::RemoveComponent(Component* c) if(Components[i] == c) { Components.erase(Components.begin() + i); - + // we're done return; } } } -void State::RemoveComponent(unsigned idx) +void Window::RemoveComponent(unsigned idx) { // free component and remove it. delete Components[idx]; Components.erase(Components.begin() + idx); } -bool State::IsFocused(const Component* c) const +bool Window::IsFocused(const Component* c) const { return c == focusedComponent_; } -void State::FocusComponent(Component* c) +void Window::FocusComponent(Component* c) { this->focusedComponent_ = c; } -void State::DoExit() +void Window::DoExit() { OnExit(); } -void State::DoInitialized() +void Window::DoInitialized() { OnInitialized(); } -void State::DoDraw() +void Window::DoDraw() { //draw for(int i = 0, sz = Components.size(); i < sz; ++i) @@ -101,12 +100,12 @@ void State::DoDraw() } else { - if( Components[i]->Position.X + Components[i]->Size.X >= 0 && - Components[i]->Position.Y + Components[i]->Size.Y >= 0 && - Components[i]->Position.X < ui::Engine::Ref().GetWidth() && - Components[i]->Position.Y < ui::Engine::Ref().GetHeight() ) + if( Components[i]->Position.X+Position.X + Components[i]->Size.X >= 0 && + Components[i]->Position.Y+Position.Y + Components[i]->Size.Y >= 0 && + Components[i]->Position.X+Position.X < ui::Engine::Ref().GetWidth() && + Components[i]->Position.Y+Position.Y < ui::Engine::Ref().GetHeight() ) { - Point scrpos(Components[i]->Position.X, Components[i]->Position.Y); + Point scrpos(Components[i]->Position.X + Position.X, Components[i]->Position.Y + Position.Y); Components[i]->Draw( Point(scrpos) ); } } @@ -115,22 +114,22 @@ void State::DoDraw() OnDraw(); } -void State::DoTick(float dt) +void Window::DoTick(float dt) { //on mouse hover for(int i = Components.size() - 1; i >= 0; --i) { if(!Components[i]->Locked && - ui::Engine::Ref().GetMouseX() >= Components[i]->Position.X && - ui::Engine::Ref().GetMouseY() >= Components[i]->Position.Y && - ui::Engine::Ref().GetMouseX() < Components[i]->Position.X + Components[i]->Size.X && - ui::Engine::Ref().GetMouseY() < Components[i]->Position.Y + Components[i]->Size.Y ) + ui::Engine::Ref().GetMouseX() >= Components[i]->Position.X+Position.X && + ui::Engine::Ref().GetMouseY() >= Components[i]->Position.Y+Position.Y && + ui::Engine::Ref().GetMouseX() < Components[i]->Position.X+Position.X + Components[i]->Size.X && + ui::Engine::Ref().GetMouseY() < Components[i]->Position.Y+Position.Y + Components[i]->Size.Y ) { - Components[i]->OnMouseHover(ui::Engine::Ref().GetMouseX() - Components[i]->Position.X, ui::Engine::Ref().GetMouseY() - Components[i]->Position.Y); + Components[i]->OnMouseHover(ui::Engine::Ref().GetMouseX() - (Components[i]->Position.X + Position.X), ui::Engine::Ref().GetMouseY() - (Components[i]->Position.Y + Position.Y)); break; } } - + //tick for(int i = 0, sz = Components.size(); i < sz; ++i) { @@ -140,7 +139,7 @@ void State::DoTick(float dt) OnTick(dt); } -void State::DoKeyPress(int key, bool shift, bool ctrl, bool alt) +void Window::DoKeyPress(int key, bool shift, bool ctrl, bool alt) { //on key press if(focusedComponent_ != NULL) @@ -152,7 +151,7 @@ void State::DoKeyPress(int key, bool shift, bool ctrl, bool alt) OnKeyPress(key, shift, ctrl, alt); } -void State::DoKeyRelease(int key, bool shift, bool ctrl, bool alt) +void Window::DoKeyRelease(int key, bool shift, bool ctrl, bool alt) { //on key unpress if(focusedComponent_ != NULL) @@ -164,7 +163,7 @@ void State::DoKeyRelease(int key, bool shift, bool ctrl, bool alt) OnKeyRelease(key, shift, ctrl, alt); } -void State::DoMouseDown(int x, int y, unsigned button) +void Window::DoMouseDown(int x, int y, unsigned button) { //on mouse click bool clickState = false; @@ -195,7 +194,7 @@ void State::DoMouseDown(int x, int y, unsigned button) OnMouseDown(x, y, button); } -void State::DoMouseMove(int x, int y, int dx, int dy) +void Window::DoMouseMove(int x, int y, int dx, int dy) { //on mouse move (if true, and inside) for(int i = Components.size() - 1; i > -1 ; --i) @@ -204,16 +203,16 @@ void State::DoMouseMove(int x, int y, int dx, int dy) { Point local (x - Components[i]->Position.X, y - Components[i]->Position.Y) , a (local.X - dx, local.Y - dy); - + Components[i]->OnMouseMoved(local.X, local.Y, dx, dy); - + if(local.X >= 0 && local.Y >= 0 && local.X < Components[i]->Size.X && local.Y < Components[i]->Size.Y ) { Components[i]->OnMouseMovedInside(local.X, local.Y, dx, dy); - + // entering? if(!( a.X >= 0 && @@ -234,7 +233,7 @@ void State::DoMouseMove(int x, int y, int dx, int dy) { Components[i]->OnMouseLeave(local.X, local.Y); } - + } } } @@ -242,7 +241,7 @@ void State::DoMouseMove(int x, int y, int dx, int dy) OnMouseMove(x, y, dx, dy); } -void State::DoMouseUp(int x, int y, unsigned button) +void Window::DoMouseUp(int x, int y, unsigned button) { //on mouse unclick for(int i = Components.size() - 1; i >= 0 ; --i) @@ -267,7 +266,7 @@ void State::DoMouseUp(int x, int y, unsigned button) OnMouseUp(x, y, button); } -void State::DoMouseWheel(int x, int y, int d) +void Window::DoMouseWheel(int x, int y, int d) { //on mouse wheel focused for(int i = Components.size() - 1; i >= 0 ; --i) @@ -279,7 +278,7 @@ void State::DoMouseWheel(int x, int y, int d) break; } } - + //on mouse wheel for(int i = Components.size() - 1; i >= 0 ; --i) { @@ -289,3 +288,4 @@ void State::DoMouseWheel(int x, int y, int d) OnMouseWheel(x, y, d); } + diff --git a/src/interface/Window.h b/src/interface/Window.h new file mode 100644 index 0000000..581b91f --- /dev/null +++ b/src/interface/Window.h @@ -0,0 +1,103 @@ +#ifndef WINDOW_H +#define WINDOW_H + +#include <vector> +#include "interface/Point.h" +#include "Engine.h" + +namespace ui +{ + +enum ChromeStyle +{ + None, Title, Resizable +}; +//class State; + class Engine; + class Component; + + /* class State + * + * A UI state. Contains all components. + */ + class Window + { + public: + Window(Point _position, Point _size); + virtual ~Window(); + + bool AllowExclusiveDrawing; //false will not call draw on objects outside of bounds + + // Add Component to state + void AddComponent(Component* c); + + // Get the number of components this state has. + unsigned GetComponentCount(); + + // Get component by index. (See GetComponentCount()) + Component* GetComponent(unsigned idx); + + // Remove a component from state. NOTE: This DOES NOT free component from memory. + void RemoveComponent(Component* c); + + // Remove a component from state. NOTE: This WILL free component from memory. + void RemoveComponent(unsigned idx); + + virtual void DoInitialized(); + virtual void DoExit(); + virtual void DoTick(float dt); + virtual void DoDraw(); + + virtual void DoMouseMove(int x, int y, int dx, int dy); + virtual void DoMouseDown(int x, int y, unsigned button); + virtual void DoMouseUp(int x, int y, unsigned button); + virtual void DoMouseWheel(int x, int y, int d); + virtual void DoKeyPress(int key, bool shift, bool ctrl, bool alt); + virtual void DoKeyRelease(int key, bool shift, bool ctrl, bool alt); + + bool IsFocused(const Component* c) const; + void FocusComponent(Component* c); + + void* UserData; + + protected: + virtual void OnInitialized() {} + virtual void OnExit() {} + virtual void OnTick(float dt) {} + virtual void OnDraw() {} + + virtual void OnMouseMove(int x, int y, int dx, int dy) {} + virtual void OnMouseDown(int x, int y, unsigned button) {} + virtual void OnMouseUp(int x, int y, unsigned button) {} + virtual void OnMouseWheel(int x, int y, int d) {} + virtual void OnKeyPress(int key, bool shift, bool ctrl, bool alt) {} + virtual void OnKeyRelease(int key, bool shift, bool ctrl, bool alt) {} + std::vector<Component*> Components; + Component* focusedComponent_; + + Point Position; + Point Size; + ChromeStyle chrome; + + }; + + +/*class Window : public State +{ +private: + ChromeStyle chrome; +public: + Window(Point _position, Point _size); + Point Position; + Point Size; + + virtual void DoTick(float dt); + virtual void DoDraw(); + + virtual void DoMouseMove(int x, int y, int dx, int dy); + virtual void DoMouseDown(int x, int y, unsigned button); + virtual void DoMouseUp(int x, int y, unsigned button); + virtual void DoMouseWheel(int x, int y, int d); +};*/ +} +#endif // WINDOW_H diff --git a/src/search/Save.h b/src/search/Save.h new file mode 100644 index 0000000..a3ef485 --- /dev/null +++ b/src/search/Save.h @@ -0,0 +1,41 @@ +#ifndef SAVE_H +#define SAVE_H + +#include <string> + +using namespace std; + +class Save +{ +private: + int id; + int votesUp, votesDown; + string userName; + string name; +public: + Save(int _id, int _votesUp, int _votesDown, string _userName, string _name): + id(_id), + votesUp(_votesUp), + votesDown(_votesDown), + userName(_userName), + name(_name) + { + } + + void SetName(string name){ this->name = name; } + string GetName(){ return name; } + + void SetUserName(string userName){ this->userName = userName; } + string GetUserName(){ return userName; } + + void SetID(int id){ this->id = id; } + int GetID(){ return id; } + + void SetVotesUp(int votesUp){ this->votesUp = votesUp; } + int GetVotesUp(){ return votesUp; } + + void SetVotesDown(int votesDown){ this->votesDown = votesDown; } + int GetVotesDown(){ return votesDown; } +}; + +#endif // SAVE_H diff --git a/src/search/SearchController.cpp b/src/search/SearchController.cpp new file mode 100644 index 0000000..cf13f2e --- /dev/null +++ b/src/search/SearchController.cpp @@ -0,0 +1,14 @@ +#include "SearchController.h" +#include "SearchModel.h" +#include "SearchView.h" +#include "interface/Panel.h" + +SearchController::SearchController() +{ + searchModel = new SearchModel(); + searchView = new SearchView(); + searchModel->AddObserver(searchView); + + //Set up interface + //windowPanel.AddChild(); +} diff --git a/src/search/SearchController.h b/src/search/SearchController.h new file mode 100644 index 0000000..8755a07 --- /dev/null +++ b/src/search/SearchController.h @@ -0,0 +1,18 @@ +#ifndef SEARCHCONTROLLER_H +#define SEARCHCONTROLLER_H + +#include "interface/Panel.h" +#include "SearchModel.h" +#include "SearchView.h" + +class SearchController +{ +private: + SearchModel * searchModel; + SearchView * searchView; + ui::Panel * windowPanel; +public: + SearchController(); +}; + +#endif // SEARCHCONTROLLER_H diff --git a/src/search/SearchModel.cpp b/src/search/SearchModel.cpp new file mode 100644 index 0000000..63188bd --- /dev/null +++ b/src/search/SearchModel.cpp @@ -0,0 +1,23 @@ +#include "SearchModel.h" +#include "Save.h" + +SearchModel::SearchModel() +{ +} + +void SearchModel::UpdateSaveList() +{ + saveList.clear(); + notifySaveListChanged(); + saveList.push_back(Save(1, 45, 5, "Simon", "Post logic gates")); + notifySaveListChanged(); +} + +void SearchModel::notifySaveListChanged() +{ + for(int i = 0; i < observers.size(); i++) + { + SearchView* cObserver = observers[i]; + cObserver->NotifySaveListChanged(this); + } +} diff --git a/src/search/SearchModel.h b/src/search/SearchModel.h new file mode 100644 index 0000000..0951577 --- /dev/null +++ b/src/search/SearchModel.h @@ -0,0 +1,23 @@ +#ifndef SEARCHMODEL_H +#define SEARCHMODEL_H + +#include <vector> +#include "Save.h" +#include "SearchView.h" + +using namespace std; + +class SearchModel +{ +private: + vector<SearchView*> observers; + vector<Save> saveList; + void notifySaveListChanged(); +public: + SearchModel(); + void AddObserver(SearchView * observer){ observers.push_back(observer); } + void UpdateSaveList(); + vector<Save> GetSaveList(); +}; + +#endif // SEARCHMODEL_H diff --git a/src/search/SearchView.cpp b/src/search/SearchView.cpp new file mode 100644 index 0000000..4b551f3 --- /dev/null +++ b/src/search/SearchView.cpp @@ -0,0 +1,10 @@ +#include "SearchView.h" + +SearchView::SearchView() +{ +} + +void SearchView::NotifySaveListChanged(SearchModel * sender) +{ + +} diff --git a/src/search/SearchView.h b/src/search/SearchView.h new file mode 100644 index 0000000..e540f21 --- /dev/null +++ b/src/search/SearchView.h @@ -0,0 +1,13 @@ +#ifndef SEARCHVIEW_H +#define SEARCHVIEW_H + +class SearchModel; + +class SearchView +{ +public: + void NotifySaveListChanged(SearchModel * sender); + SearchView(); +}; + +#endif // SEARCHVIEW_H |
