summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon 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)
commit4a60b97c700c2f1843b7e99313554cb89fb5da4e (patch)
tree3b33ef6f74a4e8a4ff5968a81b9c4c429ccaa7c6 /src
parent6273089bf486bf46ad325d72c7290ebb272bd3d8 (diff)
downloadpowder-4a60b97c700c2f1843b7e99313554cb89fb5da4e.zip
powder-4a60b97c700c2f1843b7e99313554cb89fb5da4e.tar.gz
Some minor changes
Diffstat (limited to 'src')
-rw-r--r--src/Air.h33
-rw-r--r--src/Config.h146
-rw-r--r--src/Console.h48
-rw-r--r--src/Element.h14
-rw-r--r--src/ElementFunctions.h168
-rw-r--r--src/ElementGraphics.h52
-rw-r--r--src/Elements.h280
-rw-r--r--src/GameSession.cpp6
-rw-r--r--src/Global.cpp3
-rw-r--r--src/Global.h14
-rw-r--r--src/Graphics.h172
-rw-r--r--src/Gravity.h108
-rw-r--r--src/Misc.h108
-rw-r--r--src/PowderToy.cpp21
-rw-r--r--src/Renderer.h60
-rw-r--r--src/Simulation.h241
-rw-r--r--src/Singleton.h16
-rw-r--r--src/elements/O2.cpp30
-rw-r--r--src/elements/acel.cpp58
-rw-r--r--src/elements/acid.cpp76
-rw-r--r--src/elements/amtr.cpp28
-rw-r--r--src/elements/anar.cpp27
-rw-r--r--src/elements/aray.cpp104
-rw-r--r--src/elements/bang.cpp75
-rw-r--r--src/elements/bcln.cpp40
-rw-r--r--src/elements/bcol.cpp68
-rw-r--r--src/elements/bizr.cpp44
-rw-r--r--src/elements/bmtl.cpp29
-rw-r--r--src/elements/bomb.cpp85
-rw-r--r--src/elements/boyl.cpp43
-rw-r--r--src/elements/brmt.cpp35
-rw-r--r--src/elements/btry.cpp24
-rw-r--r--src/elements/c5.cpp24
-rw-r--r--src/elements/caus.cpp35
-rw-r--r--src/elements/cbnw.cpp89
-rw-r--r--src/elements/clne.cpp32
-rw-r--r--src/elements/clst.cpp38
-rw-r--r--src/elements/co2.cpp31
-rw-r--r--src/elements/coal.cpp75
-rw-r--r--src/elements/conv.cpp45
-rw-r--r--src/elements/dest.cpp66
-rw-r--r--src/elements/deut.cpp89
-rw-r--r--src/elements/dlay.cpp48
-rw-r--r--src/elements/dstw.cpp39
-rw-r--r--src/elements/elec.cpp101
-rw-r--r--src/elements/elementmisc.cpp12
-rw-r--r--src/elements/emp.cpp128
-rw-r--r--src/elements/figh.cpp105
-rw-r--r--src/elements/fire.cpp19
-rw-r--r--src/elements/firw.cpp65
-rw-r--r--src/elements/fog.cpp22
-rw-r--r--src/elements/frzw.cpp30
-rw-r--r--src/elements/frzz.cpp25
-rw-r--r--src/elements/fsep.cpp35
-rw-r--r--src/elements/fuse.cpp41
-rw-r--r--src/elements/fwrk.cpp53
-rw-r--r--src/elements/gbmb.cpp26
-rw-r--r--src/elements/glas.cpp11
-rw-r--r--src/elements/glow.cpp28
-rw-r--r--src/elements/goo.cpp13
-rw-r--r--src/elements/gpmp.cpp34
-rw-r--r--src/elements/graphics_default.cpp23
-rw-r--r--src/elements/h2.cpp34
-rw-r--r--src/elements/hswc.cpp26
-rw-r--r--src/elements/ice.cpp23
-rw-r--r--src/elements/ignt.cpp44
-rw-r--r--src/elements/iron.cpp25
-rw-r--r--src/elements/isz.cpp14
-rw-r--r--src/elements/lava.cpp19
-rw-r--r--src/elements/lcry.cpp61
-rw-r--r--src/elements/legacy.cpp120
-rw-r--r--src/elements/ligh.cpp295
-rw-r--r--src/elements/merc.cpp70
-rw-r--r--src/elements/mort.cpp6
-rw-r--r--src/elements/nbhl.cpp6
-rw-r--r--src/elements/neut.cpp145
-rw-r--r--src/elements/newgraphics.cpp541
-rw-r--r--src/elements/none.cpp6
-rw-r--r--src/elements/nptct.cpp7
-rw-r--r--src/elements/nwhl.cpp6
-rw-r--r--src/elements/pbcn.cpp83
-rw-r--r--src/elements/pcln.cpp73
-rw-r--r--src/elements/phot.cpp84
-rw-r--r--src/elements/pipe.cpp332
-rw-r--r--src/elements/plnt.cpp55
-rw-r--r--src/elements/plsm.cpp20
-rw-r--r--src/elements/plut.cpp9
-rw-r--r--src/elements/prti.cpp79
-rw-r--r--src/elements/prto.cpp88
-rw-r--r--src/elements/pump.cpp41
-rw-r--r--src/elements/pvod.cpp30
-rw-r--r--src/elements/pyro.cpp129
-rw-r--r--src/elements/qrtz.cpp94
-rw-r--r--src/elements/rime.cpp26
-rw-r--r--src/elements/shld.cpp162
-rw-r--r--src/elements/sing.cpp104
-rw-r--r--src/elements/sltw.cpp30
-rw-r--r--src/elements/smke.cpp18
-rw-r--r--src/elements/soap.cpp234
-rw-r--r--src/elements/spng.cpp110
-rw-r--r--src/elements/sprk.cpp230
-rw-r--r--src/elements/stkm.cpp488
-rw-r--r--src/elements/stkm2.cpp29
-rw-r--r--src/elements/stor.cpp43
-rw-r--r--src/elements/swch.cpp41
-rw-r--r--src/elements/thdr.cpp38
-rw-r--r--src/elements/thrm.cpp29
-rw-r--r--src/elements/uran.cpp10
-rw-r--r--src/elements/vine.cpp19
-rw-r--r--src/elements/warp.cpp28
-rw-r--r--src/elements/watr.cpp36
-rw-r--r--src/elements/wifi.cpp35
-rw-r--r--src/elements/wire.cpp67
-rw-r--r--src/elements/wtrv.cpp21
-rw-r--r--src/elements/yest.cpp21
-rw-r--r--src/game/GameController.cpp62
-rw-r--r--src/game/GameController.h28
-rw-r--r--src/game/GameModel.cpp75
-rw-r--r--src/game/GameModel.h37
-rw-r--r--src/game/GameView.cpp83
-rw-r--r--src/game/GameView.h48
-rw-r--r--src/interface.old/Button.cpp127
-rw-r--r--src/interface.old/Component.cpp89
-rw-r--r--src/interface.old/ControlFactory.cpp11
-rw-r--r--src/interface.old/Panel.cpp23
-rw-r--r--src/interface.old/Sandbox.cpp76
-rw-r--r--src/interface.old/State.cpp233
-rw-r--r--src/interface.old/Window.cpp23
-rw-r--r--src/interface/Button.cpp26
-rw-r--r--src/interface/Button.h60
-rw-r--r--src/interface/Component.cpp14
-rw-r--r--src/interface/Component.h204
-rw-r--r--src/interface/ControlFactory.cpp5
-rw-r--r--src/interface/ControlFactory.h14
-rw-r--r--src/interface/Engine.cpp44
-rw-r--r--src/interface/Engine.h71
-rw-r--r--src/interface/Label.cpp4
-rw-r--r--src/interface/Label.h26
-rw-r--r--src/interface/Panel.cpp10
-rw-r--r--src/interface/Panel.h136
-rw-r--r--src/interface/Platform.h108
-rw-r--r--src/interface/Point.h136
-rw-r--r--src/interface/Sandbox.cpp3
-rw-r--r--src/interface/Sandbox.h39
-rw-r--r--src/interface/Window.cpp (renamed from src/interface/State.cpp)90
-rw-r--r--src/interface/Window.h103
-rw-r--r--src/search/Save.h41
-rw-r--r--src/search/SearchController.cpp14
-rw-r--r--src/search/SearchController.h18
-rw-r--r--src/search/SearchModel.cpp23
-rw-r--r--src/search/SearchModel.h23
-rw-r--r--src/search/SearchView.cpp10
-rw-r--r--src/search/SearchView.h13
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