From 69890093bd49a8659b30b83d073b8a2b3ca041a1 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Mon, 26 Aug 2013 21:02:46 +0200 Subject: [PATCH 01/28] Add special memory allocator for Lua that should take some memory stress away from heavy scripting. --- Aquaria/ScriptInterface.cpp | 10 +- Aquaria/ScriptInterface.h | 3 + BBGE/MemoryAllocatorSmallBlock.cpp | 284 +++++++++++++++++++++++++++++ BBGE/MemoryAllocatorSmallBlock.h | 100 ++++++++++ BBGE/bithacks.h | 84 +++++++++ 5 files changed, 479 insertions(+), 2 deletions(-) create mode 100644 BBGE/MemoryAllocatorSmallBlock.cpp create mode 100644 BBGE/MemoryAllocatorSmallBlock.h create mode 100644 BBGE/bithacks.h diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index dff9401..a6203bd 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -9952,7 +9952,7 @@ static const struct { //============================================================================================ ScriptInterface::ScriptInterface() -: baseState(NULL) +: baseState(NULL), _sballoc(8, 128) { } @@ -9975,9 +9975,15 @@ void ScriptInterface::reset() init(); } +void *ScriptInterface::the_alloc(void *ud, void *ptr, size_t osize, size_t nsize) +{ + ScriptInterface *this_ = (ScriptInterface*)ud; + return this_->_sballoc.Alloc(ptr, nsize, osize); +} + lua_State *ScriptInterface::createLuaVM() { - lua_State *state = lua_open(); /* opens Lua */ + lua_State *state = lua_newstate(the_alloc, this); /* opens Lua */ luaopen_base(state); /* opens the basic library */ luaopen_table(state); /* opens the table library */ luaopen_string(state); /* opens the string lib. */ diff --git a/Aquaria/ScriptInterface.h b/Aquaria/ScriptInterface.h index 2815764..65de7a1 100644 --- a/Aquaria/ScriptInterface.h +++ b/Aquaria/ScriptInterface.h @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define SCRIPTINTERFACE_H #include "../BBGE/Base.h" +#include "../BBGE/MemoryAllocatorSmallBlock.h" struct lua_State; @@ -105,8 +106,10 @@ protected: void destroyLuaVM(lua_State *state); lua_State *createLuaThread(const std::string &file); int destroyLuaThread(const std::string &file, lua_State *thread); + static void *the_alloc(void *ud, void *ptr, size_t osize, size_t nsize); lua_State *baseState; + SmallBlockAllocator _sballoc; }; #endif diff --git a/BBGE/MemoryAllocatorSmallBlock.cpp b/BBGE/MemoryAllocatorSmallBlock.cpp new file mode 100644 index 0000000..62b523f --- /dev/null +++ b/BBGE/MemoryAllocatorSmallBlock.cpp @@ -0,0 +1,284 @@ +// Public domain + +// Aquaria specific... +#include "Base.h" + +#include "algorithmx.h" +#include "MemoryAllocatorSmallBlock.h" +#include "bithacks.h" + +//#define DD(...) logdev(__VA_ARGS__) +#define DD(...) +#define logdev(...) +#define logerror(...) +#define ASSERT(x) assert(x) + + +SmallBlockAllocator::SmallBlockAllocator(unsigned int blockSizeMin, + unsigned int blockSizeMax, + unsigned int blockSizeIncr /* = 8 */, + unsigned int elemsPerBlockMin /* = 64 */, + unsigned int elemsPerBlockMax /* = 2048 */) + : _blockSizeMin(blockSizeMin) + , _blockSizeMax(blockSizeMax) + , _blockSizeIncr(blockSizeIncr) + , _elemsPerBlockMin(elemsPerBlockMin) + , _elemsPerBlockMax(elemsPerBlockMax) +{ + ASSERT(_blockSizeIncr % 4 == 0); // less than 4 bytes makes no sense + ASSERT(_blockSizeMin % _blockSizeIncr == 0); + ASSERT(_blockSizeMax % _blockSizeIncr == 0); + ASSERT((_blockSizeMax - _blockSizeMin) % _blockSizeIncr == 0); + unsigned int c = ((_blockSizeMax - _blockSizeMin) / _blockSizeIncr) + 1; + logdev("SBA: Using %u distinct block sizes from %u - %u bytes", c, _blockSizeMin, _blockSizeMax); + _blocks = new Block*[c]; // TODO: Do we really want to use dynamic allocation here? + memset(_blocks, 0, c * sizeof(Block*)); +} + +SmallBlockAllocator::~SmallBlockAllocator() +{ + while(_allblocks.size()) + { + Block *blk = _allblocks.back(); + logerror("~SmallBlockAllocator(): Warning: Leftover block with %u/%u elements, %uB each", + blk->maxElems, blk->maxElems - blk->freeElems, blk->elemSize); + _FreeBlock(blk); + } + delete [] _blocks; +} + +void *SmallBlockAllocator::Alloc(void *ptr, size_t newsize, size_t oldsize) +{ + DD("SBA::Alloc() ptr = %p; newsize = %u, oldsize = %u", ptr, newsize, oldsize); + + if(ptr) + { + if(!newsize) + { + _Free(ptr, oldsize); + return NULL; + } + else if(newsize == oldsize) + return ptr; + else + return _Realloc(ptr, newsize, oldsize); + } + else + { + if(newsize) + return _Alloc(newsize); + } + return NULL; +} + +SmallBlockAllocator::Block *SmallBlockAllocator::_AllocBlock(unsigned int elemCount, unsigned int elemSize) +{ + DD("SBA: _AllocBlock: elemCount = %u, elemSize = %u", elemCount, elemSize); + + const unsigned int bitsPerInt = (sizeof(unsigned int) * 8); // 32 + unsigned int bitmapInts = (elemCount + (bitsPerInt - 1)) / bitsPerInt; + void *ptr = malloc( + (sizeof(Block) - sizeof(unsigned int)) // block header without bitmap[1] + + (bitmapInts * sizeof(unsigned int)) // actual bitmap size + + (elemCount * elemSize) // data size + ); + + if(!ptr) + return NULL; + Block *blk = (Block*)ptr; + memset(&blk->bitmap[0], 0xff, bitmapInts * sizeof(unsigned int)); // all free + blk->elemSize = elemSize; + blk->maxElems = elemCount; + blk->freeElems = elemCount; + blk->bitmapInts = bitmapInts; + blk->next = NULL; + blk->prev = NULL; + + // using insertion sort + std::vector::iterator insertit = std::lower_bound(_allblocks.begin(), _allblocks.end(), blk); + _allblocks.insert(insertit, blk); + + return blk; +} + +void SmallBlockAllocator::_FreeBlock(Block *blk) +{ + DD("SBA: _FreeBlock: elemCount = %u, elemSize = %u", blk->maxElems, blk->elemSize); + + if(blk->prev) + blk->prev->next = blk->next; + else + _blocks[GetIndexForElemSize(blk->elemSize)] = blk->next; + + if(blk->next) + blk->next->prev = blk->prev; + + free(blk); + + // keeps the vector sorted + _allblocks.erase(std::remove(_allblocks.begin(), _allblocks.end(), blk), _allblocks.end()); +} + + +SmallBlockAllocator::Block *SmallBlockAllocator::_AppendBlock(unsigned int elemSize) +{ + unsigned int idx = GetIndexForElemSize(elemSize); + Block *blk = _blocks[idx]; + unsigned int elemsPerBlock = _elemsPerBlockMin; + if(blk) + { + while(blk->next) + blk = blk->next; + elemsPerBlock = blk->maxElems * 2; // new block is double the size + if(elemsPerBlock > _elemsPerBlockMax) + elemsPerBlock = _elemsPerBlockMax; + } + + unsigned int blockElemSize = ((elemSize + (_blockSizeIncr - 1)) / _blockSizeIncr) * _blockSizeIncr; + ASSERT(blockElemSize >= elemSize); + + Block *newblk = _AllocBlock(elemsPerBlock, blockElemSize); + if(!newblk) + return NULL; + + if(blk) + { + blk->next = newblk; // append to list + newblk->prev = blk; + } + else + _blocks[idx] = newblk; // list head + + return newblk; +} + +SmallBlockAllocator::Block *SmallBlockAllocator::_GetFreeBlock(unsigned int elemSize) +{ + unsigned int idx = GetIndexForElemSize(elemSize); + Block *blk = _blocks[idx]; + while(blk && !blk->freeElems) + blk = blk->next; + return blk; +} + +void *SmallBlockAllocator::Block::allocElem() +{ + ASSERT(freeElems); + unsigned int i = 0; + for( ; !bitmap[i]; ++i) // as soon as one isn't all zero, there's a free slot + ASSERT(i < bitmapInts); + ASSERT(i < bitmapInts); + int freeidx = bithacks::ctz(bitmap[i]); + ASSERT(bitmap[i] & (1 << freeidx)); // make sure this is '1' (= free) + bitmap[i] &= ~(1 << freeidx); // put '0' where '1' was (-> mark as non-free) + --freeElems; + const unsigned int offs = (i * sizeof(unsigned int) * 8 * elemSize); // skip forward i bitmaps (32 elems each) + unsigned char *ret = getPtr() + offs + (elemSize * freeidx); + ASSERT(contains(ret)); + return ret; +} + +bool SmallBlockAllocator::Block::contains(unsigned char *ptr) const +{ + const unsigned char *pp = getPtr(); + + if(ptr < pp) + return false; // pointer is out of range (1) + if(ptr >= pp + (maxElems * elemSize)) + return false; // pointer is out of range (2) + + return true; +} + +void SmallBlockAllocator::Block::freeElem(unsigned char *ptr) +{ + ASSERT(contains(ptr)); + ASSERT(freeElems < maxElems); // make sure the block is not all free + + const ptrdiff_t p = ptr - getPtr(); + ASSERT((p % elemSize) == 0); // make sure alignment is right + const unsigned int idx = p / elemSize; + const unsigned int bitsPerInt = sizeof(unsigned int) * 8; // 32 + const unsigned int bitmapIdx = idx / bitsPerInt; + const unsigned int bitIdx = idx % bitsPerInt; + ASSERT(bitmapIdx < bitmapInts); + ASSERT(!(bitmap[bitmapIdx] & (1 << bitIdx))); // make sure this is '0' (= used) + + bitmap[bitmapIdx] |= (1 << bitIdx); // put '1' where '0' was (-> mark as free) + ++freeElems; + +#ifdef _DEBUG + memset(ptr, 0xfa, elemSize); +#endif +} + +void *SmallBlockAllocator::_FallbackAlloc(unsigned int size) +{ + return malloc(size); +} + +void SmallBlockAllocator::_FallbackFree(void *ptr) +{ + free(ptr); +} + +void *SmallBlockAllocator::_Alloc(unsigned int size) +{ + if(size > _blockSizeMax) + return _FallbackAlloc(size); + + Block *blk = _GetFreeBlock(size); + ASSERT(!blk || blk->freeElems); + if(!blk) + { + blk = _AppendBlock(size); + if(!blk) + return _FallbackAlloc(size); + } + return blk->allocElem(); +} + +bool SmallBlockAllocator::Block_ptr_cmp(const Block *blk, const void *ptr) +{ + return blk->getEndPtr() < ((unsigned char*)ptr); +} + +SmallBlockAllocator::Block *SmallBlockAllocator::_FindBlockContainingPtr(void *ptr) +{ + // MSVC's std::lower_bound uses iterator debug checks in debug mode, + // which breaks Block_ptr_cmp() because the left and right types are different. + std::vector::iterator it = stdx_fg::lower_bound(_allblocks.begin(), _allblocks.end(), ptr, Block_ptr_cmp); + return (it != _allblocks.end() && (*it)->contains((unsigned char*)ptr)) ? *it : NULL; +} + +void SmallBlockAllocator::_Free(void *ptr, unsigned int size) +{ + if(size <= _blockSizeMax) + { + Block *blk = _FindBlockContainingPtr(ptr); + if(blk) + { + ASSERT(blk->elemSize >= size); // ptr might be from a larger block in case _Realloc() failed to shrink + blk->freeElem((unsigned char*)ptr); + if(blk->freeElems == blk->maxElems) + _FreeBlock(blk); // remove if completely unused + return; + } + } + _FallbackFree(ptr); +} + +void *SmallBlockAllocator::_Realloc(void *ptr, unsigned int newsize, unsigned int oldsize) +{ + void *newptr = _Alloc(newsize); + + // If the new allocation failed, just re-use the old pointer if it was a shrink request + // This also satisfies Lua, which assumes that realloc() shrink requests cannot fail + if(!newptr) + return newsize <= oldsize ? ptr : NULL; + + memcpy(newptr, ptr, std::min(oldsize, newsize)); + _Free(ptr, oldsize); + return newptr; +} + diff --git a/BBGE/MemoryAllocatorSmallBlock.h b/BBGE/MemoryAllocatorSmallBlock.h new file mode 100644 index 0000000..5dd9c52 --- /dev/null +++ b/BBGE/MemoryAllocatorSmallBlock.h @@ -0,0 +1,100 @@ +#ifndef MEMORY_ALLOCATOR_SMALL_BLOCK_H +#define MEMORY_ALLOCATOR_SMALL_BLOCK_H + +/* Optimized memory allocator for small & frequent (de-)allocations. + * Low memory overhead. Used for Lua. + * Inspired by http://dns.achurch.org/cgi-bin/hg/aquaria-psp/file/tip/PSP/src/lalloc.c +*/ + +// Originally made for LV3proj_ng (https://github.com/fgenesis/lv3proj_ng) +// Hacked in shape for use in Aquaria +// Public domain + + +#include + +class SmallBlockAllocator +{ +public: + + SmallBlockAllocator(unsigned int blockSizeMin, unsigned int blockSizeMax, unsigned int blockSizeIncr = 8, + unsigned int elemsPerBlockMin = 64, unsigned int elemsPerBlockMax = 2048); + + ~SmallBlockAllocator(); + + void *Alloc(void *ptr, size_t newsize, size_t oldsize); + + +private: + + void *_Alloc(unsigned int size); + void *_Realloc(void *ptr, unsigned int newsize, unsigned int oldsize); + void _Free(void* ptr, unsigned int size); + + void *_FallbackAlloc(unsigned int size); + void _FallbackFree(void *ptr); + + struct Block + { + // block header start + Block *next; + Block *prev; + unsigned short maxElems; + unsigned short freeElems; + unsigned short elemSize; + unsigned short bitmapInts; + // block header end + + unsigned int bitmap[1]; // variable sized + // actual storage memory starts after bitmap[bitmapInts] + + inline unsigned char *getPtr() + { + return (unsigned char*)&bitmap[bitmapInts]; + } + inline const unsigned char *getPtr() const + { + return (unsigned char*)&bitmap[bitmapInts]; + } + inline unsigned char *getEndPtr() + { + return getPtr() + (maxElems * elemSize); + } + inline const unsigned char *getEndPtr() const + { + return getPtr() + (maxElems * elemSize); + } + + void *allocElem(); + void freeElem(unsigned char *ptr); + bool contains(unsigned char *ptr) const; + }; + + Block *_AllocBlock(unsigned int elemCount, unsigned int elemSize); + void _FreeBlock(Block *blk); + Block *_AppendBlock(unsigned int elemSize); + Block *_GetFreeBlock(unsigned int elemSize); // NULL if none free + + Block *_FindBlockContainingPtr(void *ptr); + + inline unsigned int GetIndexForElemSize(unsigned int elemSize) + { + //ASSERT(elemSize); + //ASSERT(elemSize <= _blockSizeMax); + return ((elemSize + (_blockSizeIncr - 1)) / _blockSizeIncr) - 1; + } + + static bool Block_ptr_cmp(const Block *blk, const void *ptr); + + Block **_blocks; + std::vector _allblocks; // always sorted by pointer address + + unsigned int _blockSizeMin; + unsigned int _blockSizeMax; + unsigned int _blockSizeIncr; + + unsigned int _elemsPerBlockMin; + unsigned int _elemsPerBlockMax; +}; + +#endif diff --git a/BBGE/bithacks.h b/BBGE/bithacks.h new file mode 100644 index 0000000..db9db48 --- /dev/null +++ b/BBGE/bithacks.h @@ -0,0 +1,84 @@ +#ifndef BITHACKS_H +#define BITHACKS_H + +#ifdef _MSC_VER +# include +#endif + +namespace bithacks { + +typedef unsigned int uint32; +typedef int int32; + +// floor to next power of 2 +inline uint32 flp2(uint32 x) +{ + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return x - (x >> 1); +} + +// ceil to next power of 2 +inline uint32 clp2(uint32 x) +{ + --x; + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return x + 1; +} + +inline uint32 popcnt(uint32 x) +{ + x -= ((x >> 1) & 0x55555555); + x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); + x = (((x >> 4) + x) & 0x0f0f0f0f); + x += (x >> 8); + x += (x >> 16); + return x & 0x0000003f; +} + +inline uint32 ctz(uint32 x) +{ +#ifdef __GNUC__ + return __builtin_ctz(x); +#elif defined(_MSC_VER) && defined(_M_IX86) + unsigned long r = 0; + _BitScanForward(&r, x); + return r; +#else + return popcnt((x & -x) - 1); +#endif +} + +inline unsigned int clz(uint32 x) +{ +#ifdef __GNUC__ + return __builtin_clz(x); +#elif defined(_MSC_VER) && defined(_M_IX86) + unsigned long r = 0; + _BitScanReverse(&r, x); + return r; +#else + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return 32 - popcnt(x); +#endif +} + + + + + + +}; // end namespace bithacks + +#endif From f85d6c213e1e6ea314e8cd0cde3b39a250c9e9a3 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Mon, 26 Aug 2013 21:03:02 +0200 Subject: [PATCH 02/28] vcproj update --- win/vc90/BBGE.vcproj | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/win/vc90/BBGE.vcproj b/win/vc90/BBGE.vcproj index 3b11171..d081ecf 100644 --- a/win/vc90/BBGE.vcproj +++ b/win/vc90/BBGE.vcproj @@ -212,6 +212,10 @@ RelativePath="..\..\BBGE\BaseText.h" > + + @@ -332,6 +336,14 @@ RelativePath="..\..\BBGE\MathFunctions.h" > + + + + From d4038c1ad92d5bb69fce12df65c3b82b48b30e0f Mon Sep 17 00:00:00 2001 From: fgenesis Date: Mon, 26 Aug 2013 22:25:36 +0200 Subject: [PATCH 03/28] Fix build on Linux/OSX --- BBGE/MemoryAllocatorSmallBlock.cpp | 11 +++++++++-- CMakeLists.txt | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/BBGE/MemoryAllocatorSmallBlock.cpp b/BBGE/MemoryAllocatorSmallBlock.cpp index 62b523f..c51f964 100644 --- a/BBGE/MemoryAllocatorSmallBlock.cpp +++ b/BBGE/MemoryAllocatorSmallBlock.cpp @@ -7,11 +7,18 @@ #include "MemoryAllocatorSmallBlock.h" #include "bithacks.h" -//#define DD(...) logdev(__VA_ARGS__) +#include + +//#define DD(...) fprintf(stderr, __VA_ARGS__) #define DD(...) #define logdev(...) #define logerror(...) -#define ASSERT(x) assert(x) + +#ifdef NDEBUG +# define ASSERT(x) +#else +# define ASSERT(x) assert(x) +#endif SmallBlockAllocator::SmallBlockAllocator(unsigned int blockSizeMin, diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bb2171..1990d5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -448,6 +448,7 @@ SET(BBGE_SRCS ${BBGEDIR}/LensFlare.cpp ${BBGEDIR}/Localization.cpp ${BBGEDIR}/Math.cpp + ${BBGEDIR}/MemoryAllocatorSmallBlock.cpp ${BBGEDIR}/MT.cpp ${BBGEDIR}/ParticleEffect.cpp ${BBGEDIR}/ParticleManager.cpp From a7447cc59904bbc12ba4ba2c958fe8f86a083e88 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Tue, 27 Aug 2013 01:42:31 +0200 Subject: [PATCH 04/28] Allow nodes to catch ACTION_SECONDARY. --- Aquaria/Game.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 00b18be..f4a105f 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -6843,6 +6843,7 @@ void Game::bindInput() dsq->user.control.actionSet.importAction(this, "PrimaryAction", ACTION_PRIMARY); + dsq->user.control.actionSet.importAction(this, "SecondaryAction", ACTION_SECONDARY); dsq->user.control.actionSet.importAction(this, "Escape", ACTION_ESC); From 01d9211a34ca2c7f3fe99550802676a39712053a Mon Sep 17 00:00:00 2001 From: fgenesis Date: Wed, 28 Aug 2013 04:20:36 +0200 Subject: [PATCH 05/28] Little script interface changes: - Add avatar_isSwimming() - toggleInput() does now parse bools correctly - pickupGem() returns gem ID - Change in entity_doCollisionAvoidance(): * Add support for ignore obs * One arg was shifted, this is now fixed but not sure if it adds a problem somewhere. --- Aquaria/ScriptInterface.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index a6203bd..634a44c 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -3090,6 +3090,11 @@ luaFunc(avatar_isRolling) luaReturnBool(dsq->game->avatar->isRolling()); } +luaFunc(avatar_isSwimming) +{ + luaReturnBool(dsq->game->avatar->isSwimming()); +} + luaFunc(avatar_isOnWall) { bool v = dsq->game->avatar->state.lockedToWall; @@ -5672,13 +5677,14 @@ luaFunc(entity_doCollisionAvoidance) int useVel2 = lua_tonumber(L, 6); bool onlyVP = getBool(L, 7); + int ignoreObs = lua_tointeger(L, 8); if (e) { if (useVel2) - ret = e->doCollisionAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), &e->vel2, lua_tonumber(L, 5), onlyVP); + ret = e->doCollisionAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), &e->vel2, lua_tonumber(L, 5), ignoreObs, onlyVP); else - ret = e->doCollisionAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), 0, lua_tonumber(L, 5)); + ret = e->doCollisionAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), 0, lua_tonumber(L, 5), ignoreObs); } luaReturnBool(ret); } @@ -5794,7 +5800,7 @@ luaFunc(entity_followEntity) luaFunc(toggleInput) { - int v = lua_tointeger(L, 1); + bool v = getBool(L, 1); if (v) dsq->game->avatar->enableInput(); else @@ -7716,7 +7722,7 @@ luaFunc(entity_setWeight) luaFunc(pickupGem) { dsq->continuity.pickupGem(getString(L), !getBool(L, 2)); - luaReturnNil(); + luaReturnInt(dsq->continuity.gems.size() - 1); } luaFunc(setGemPosition) @@ -8860,6 +8866,7 @@ static const struct { luaRegister(avatar_isBursting), luaRegister(avatar_isLockable), luaRegister(avatar_isRolling), + luaRegister(avatar_isSwimming), luaRegister(avatar_isOnWall), luaRegister(avatar_isShieldActive), luaRegister(avatar_setShieldActive), From 18a19ca1153852b2ebcea253a36d50a1c8b204b8 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Wed, 28 Aug 2013 04:33:12 +0200 Subject: [PATCH 06/28] Disable path finding debug spam. --- Aquaria/PathFinding.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Aquaria/PathFinding.cpp b/Aquaria/PathFinding.cpp index c683cb2..9080e09 100644 --- a/Aquaria/PathFinding.cpp +++ b/Aquaria/PathFinding.cpp @@ -408,9 +408,9 @@ void PathFinding::molestPath(VectorPath &path) } } } - std::ostringstream os; + /*std::ostringstream os; os << "pushing node [" << i << "] out by (" << n.x << ", " << n.y << ") - dist: " << dist << " maxDist: " << maxDist; - debugLog(os.str()); + debugLog(os.str());*/ //path.getPathNode(i)->value += n; normals[i] = n; } @@ -453,9 +453,9 @@ void PathFinding::molestPath(VectorPath &path) //bowl_loop: sz=path.getNumPathNodes(); - std::ostringstream os; + /*std::ostringstream os; os << "kill bowls # " << runs; - debugLog(os.str()); + debugLog(os.str());*/ for (i = start; i < sz-1; i++) { @@ -502,9 +502,9 @@ void PathFinding::molestPath(VectorPath &path) */ { path.removeNodes(i+1, lastSuccessNode-1); - std::ostringstream os; + /*std::ostringstream os; os << "killing bowl: " << i+1 << " - " << lastSuccessNode-1; - debugLog(os.str()); + debugLog(os.str());*/ //start = lastSuccessNode - (lastSuccessNode-i); //start = i+1; //i = i+1; @@ -516,7 +516,7 @@ void PathFinding::molestPath(VectorPath &path) } sz = path.getNumPathNodes(); } - debugLog("kill bowls done"); + //debugLog("kill bowls done"); sz=path.getNumPathNodes(); // remove last node From 4f6447b58e49e8b1eef7d29d4dbb9ca12e0f7abe Mon Sep 17 00:00:00 2001 From: fgenesis Date: Thu, 29 Aug 2013 03:58:50 +0200 Subject: [PATCH 07/28] Script interface extensions: - shot_setTargetPoint() - shot_getTargetPoint() - entity_getTargetPriority() - fix oversight in entity_doEntityAvoidance() - entity_getTargetRange() - getJoystickAxisLeft() - getJoystickAxisRight() --- Aquaria/ScriptInterface.cpp | 46 ++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 634a44c..a17519e 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -2177,6 +2177,20 @@ luaFunc(shot_setTrailPrt) luaReturnNil(); } +luaFunc(shot_setTargetPoint) +{ + Shot *shot = getShot(L); + if (shot) + shot->setTargetPoint(lua_tointeger(L, 2)); + luaReturnNil(); +} + +luaFunc(shot_getTargetPoint) +{ + Shot *shot = getShot(L); + luaReturnInt(shot ? shot->targetPt : 0); +} + luaFunc(entity_setVel) { Entity *e = entity(L); @@ -2502,6 +2516,12 @@ luaFunc(entity_setTargetPriority) luaReturnNil(); } +luaFunc(entity_getTargetPriority) +{ + Entity *e = entity(L); + luaReturnInt(e ? e->targetPriority : 0); +} + luaFunc(isQuitFlag) { luaReturnBool(dsq->isQuitFlag()); @@ -5675,7 +5695,7 @@ luaFunc(entity_doCollisionAvoidance) Entity *e = entity(L); bool ret = false; - int useVel2 = lua_tonumber(L, 6); + bool useVel2 = getBool(L, 6); bool onlyVP = getBool(L, 7); int ignoreObs = lua_tointeger(L, 8); @@ -5876,6 +5896,12 @@ luaFunc(entity_setTargetRange) luaReturnNil(); } +luaFunc(entity_getTargetRange) +{ + Entity *e = entity(L); + luaReturnInt(e ? e->getTargetRange() : 0); +} + luaFunc(entity_clearTargetPoints) { Entity *e = entity(L); @@ -7565,6 +7591,18 @@ luaFunc(getInputMode) luaReturnInt(dsq->inputMode); } +luaFunc(getJoystickAxisLeft) +{ + Vector v = core->joystick.position; + luaReturnVec2(v.x, v.y); +} + +luaFunc(getJoystickAxisRight) +{ + Vector v = core->joystick.rightStick; + luaReturnVec2(v.x, v.y); +} + luaFunc(quit) { #ifdef AQUARIA_DEMO @@ -8486,6 +8524,7 @@ static const struct { luaRegister(entity_getNumTargetPoints), luaRegister(entity_setTargetRange), + luaRegister(entity_getTargetRange), luaRegister(bone_addSegment), @@ -8528,6 +8567,8 @@ static const struct { luaRegister(disableInput), luaRegister(getInputMode), + luaRegister(getJoystickAxisLeft), + luaRegister(getJoystickAxisRight), luaRegister(setMousePos), luaRegister(getMousePos), @@ -8615,6 +8656,7 @@ static const struct { luaRegister(entity_stopTimer), luaRegister(entity_stopPull), luaRegister(entity_setTargetPriority), + luaRegister(entity_getTargetPriority), luaRegister(entity_setEntityType), luaRegister(entity_getEntityType), @@ -8981,6 +9023,8 @@ static const struct { luaRegister(shot_setCheckDamageTarget), luaRegister(shot_isCheckDamageTarget), luaRegister(shot_setTrailPrt), + luaRegister(shot_setTargetPoint), + luaRegister(shot_getTargetPoint), luaRegister(entity_pathBurst), luaRegister(entity_handleShotCollisions), luaRegister(entity_handleShotCollisionsSkeletal), From 396f091c852192aae2af28be20d4719974b84795 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sat, 31 Aug 2013 16:14:05 +0200 Subject: [PATCH 08/28] Add Lua functions: - quad_isRenderBeforeParent() - quad_setRenderBorder() - quad_isRenderBorder() - quad_setRenderCenter() - quad_isRenderCenter() - quad_borderAlpha() - quad_getBorderAlpha() - node_getShape() - text_setAlign() Constants: ALIGN_CENTER, ALIGN_LEFT, PATHSHAPE_RECT, PATHSHAPE_CIRCLE --- Aquaria/ScriptInterface.cpp | 80 ++++++++++++++++++++++++++++++++++++- BBGE/BaseText.h | 1 + BBGE/BitmapFont.h | 2 +- BBGE/DebugFont.h | 2 +- 4 files changed, 82 insertions(+), 3 deletions(-) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index a17519e..e8bd6a0 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -1145,6 +1145,12 @@ luaFunc(obj_setRenderBeforeParent) luaReturnNil(); } +luaFunc(obj_isRenderBeforeParent) +{ + RenderObject *r = robj(L); + luaReturnBool(r ? r->renderBeforeParent : false); +} + // Not so pretty: Because RenderObject has a `velocity' vector, // and Entity has `vel' ADDITIONALLY, we need to use // extra functions to manage RenderObject's velocities. @@ -1606,6 +1612,49 @@ luaFunc(quad_isRepeatTexture) luaReturnBool(b ? b->isRepeatingTextureToFill() : false); } +luaFunc(quad_setRenderBorder) +{ + Quad *b = getQuad(L); + if (b) + b->renderBorder = getBool(L, 2); + luaReturnNil(); +} + +luaFunc(quad_isRenderBorder) +{ + Quad *b = getQuad(L); + luaReturnBool(b ? b->renderBorder : false); +} + +luaFunc(quad_setRenderCenter) +{ + Quad *b = getQuad(L); + if (b) + b->renderBorder = getBool(L, 2); + luaReturnNil(); +} + +luaFunc(quad_isRenderCenter) +{ + Quad *b = getQuad(L); + luaReturnBool(b ? b->renderBorder : false); +} + + +luaFunc(quad_borderAlpha) +{ + Quad *b = getQuad(L); + if (b) + b->borderAlpha = lua_tonumber(L, 2); + luaReturnNil(); +} + +luaFunc(quad_getBorderAlpha) +{ + Quad *b = getQuad(L); + luaReturnNum(b ? b->borderAlpha : 0.0f); +} + // --- standard set/get functions for each type, wrapping RenderObject functions --- #define MK_FUNC(base, getter, prefix, suffix) \ @@ -1674,6 +1723,7 @@ luaFunc(quad_isRepeatTexture) RO_FUNC(getter, prefix, setLayer ) \ RO_FUNC(getter, prefix, getLayer ) \ RO_FUNC(getter, prefix, setRenderBeforeParent) \ + RO_FUNC(getter, prefix, isRenderBeforeParent) \ RO_FUNC(getter, prefix, addChild ) \ RO_FUNC(getter, prefix, fh ) \ RO_FUNC(getter, prefix, fv ) \ @@ -1710,7 +1760,13 @@ luaFunc(quad_isRepeatTexture) Q_FUNC(getter, prefix, setSegs ) \ Q_FUNC(getter, prefix, setRepeatTexture) \ Q_FUNC(getter, prefix, isRepeatTexture ) \ - Q_FUNC(getter, prefix, setRepeatScale ) + Q_FUNC(getter, prefix, setRepeatScale ) \ + Q_FUNC(getter, prefix, setRenderBorder ) \ + Q_FUNC(getter, prefix, isRenderBorder ) \ + Q_FUNC(getter, prefix, setRenderCenter ) \ + Q_FUNC(getter, prefix, isRenderCenter ) \ + Q_FUNC(getter, prefix, borderAlpha ) \ + Q_FUNC(getter, prefix, getBorderAlpha ) // This should reflect the internal class hierarchy, // e.g. a Beam is a Quad, so it can use quad_* functions @@ -4727,6 +4783,12 @@ luaFunc(node_setPosition) luaReturnNil(); } +luaFunc(node_getShape) +{ + Path *p = path(L); + luaReturnInt(p ? p->pathShape : 0); +} + luaFunc(registerSporeDrop) { @@ -8269,6 +8331,14 @@ luaFunc(text_setWidth) luaReturnNil(); } +luaFunc(text_setAlign) +{ + BaseText *txt = getText(L); + if (txt) + txt->setAlign((Align)lua_tointeger(L, 2)); + luaReturnNil(); +} + luaFunc(loadShader) { int handle = 0; @@ -9099,6 +9169,7 @@ static const struct { luaRegister(node_getSize), luaRegister(node_setEffectOn), luaRegister(node_isEffectOn), + luaRegister(node_getShape), luaRegister(toggleSteam), luaRegister(toggleVersionLabel), @@ -9271,6 +9342,7 @@ static const struct { luaRegister(text_setText), luaRegister(text_setFontSize), luaRegister(text_setWidth), + luaRegister(text_setAlign), luaRegister(loadShader), luaRegister(createShader), @@ -9996,6 +10068,12 @@ static const struct { luaConstant(SEE_MAP_NEVER), luaConstant(SEE_MAP_DEFAULT), luaConstant(SEE_MAP_ALWAYS), + + luaConstant(ALIGN_CENTER), + luaConstant(ALIGN_LEFT), + + luaConstant(PATHSHAPE_RECT), + luaConstant(PATHSHAPE_CIRCLE), }; //============================================================================================ diff --git a/BBGE/BaseText.h b/BBGE/BaseText.h index d6bcb6c..a3be629 100644 --- a/BBGE/BaseText.h +++ b/BBGE/BaseText.h @@ -12,6 +12,7 @@ public: virtual void setText(const std::string& text) = 0; virtual void setWidth(int width) = 0; virtual void setFontSize(int sz) = 0; + virtual void setAlign(Align a) = 0; }; diff --git a/BBGE/BitmapFont.h b/BBGE/BitmapFont.h index 0ddfe79..730e265 100644 --- a/BBGE/BitmapFont.h +++ b/BBGE/BitmapFont.h @@ -63,7 +63,7 @@ public: bool isScrollingText(); void stopScrollingText(); bool isEmpty(); - void setAlign(Align align); + virtual void setAlign(Align align); std::string getText(); int getWidthOnScreen(); void loadSpacingMap(const std::string &file); diff --git a/BBGE/DebugFont.h b/BBGE/DebugFont.h index d11c17f..c8620fd 100644 --- a/BBGE/DebugFont.h +++ b/BBGE/DebugFont.h @@ -32,7 +32,7 @@ public: void setWidth(int width); void setFontSize(int sz); int getNumLines() { return lines.size(); } - void setAlign(Align align); + virtual void setAlign(Align align); protected: int fontDrawSize, textWidth; void formatText(); From 31ab72334b780d6dbedb7db8af2912ef909ff817 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sat, 31 Aug 2013 16:49:22 +0200 Subject: [PATCH 09/28] Fix copy-paste oops. --- Aquaria/ScriptInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index e8bd6a0..12ed8fc 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -1630,14 +1630,14 @@ luaFunc(quad_setRenderCenter) { Quad *b = getQuad(L); if (b) - b->renderBorder = getBool(L, 2); + b->renderCenter = getBool(L, 2); luaReturnNil(); } luaFunc(quad_isRenderCenter) { Quad *b = getQuad(L); - luaReturnBool(b ? b->renderBorder : false); + luaReturnBool(b ? b->renderCenter : false); } From a91a22f46365f880d9efe664e8527581fb457200 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Wed, 4 Sep 2013 16:07:46 +0200 Subject: [PATCH 10/28] Cleaning out some dead code. This adds a small compile error, to be fixed in next commit. --- Aquaria/Avatar.cpp | 101 +++-------------- Aquaria/Avatar.h | 6 +- Aquaria/CollideEntity.cpp | 63 ----------- Aquaria/CollideEntity.h | 5 +- Aquaria/Entity.h | 3 +- Aquaria/ScriptedEntity.cpp | 215 +++---------------------------------- Aquaria/ScriptedEntity.h | 2 +- 7 files changed, 30 insertions(+), 365 deletions(-) diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index 4a8f518..805f31c 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -93,7 +93,6 @@ const float QUICK_SONG_CAST_DELAY = 0.4; const float BURST_RECOVER_RATE = 1.2; // 3.0 // 0.75 const float BURST_USE_RATE = 1.5; //0.9 //1.5; -const float BURST_DELAY = 0.1; const float BURST_ACCEL = 4000; //2000 // 1000 // Minimum time between two splash effects (seconds). @@ -265,13 +264,6 @@ void Avatar::postInit() void Avatar::onAnimationKeyPassed(int key) { - if (swimming && !isRolling() && !bursting && _isUnderWater) - { - if (key == 0 || key == 2) - { - //core->sound->playSfx("SwimKick", 255, 0, 1000+getMaxSpeed()/10.0f); - } - } Entity::onAnimationKeyPassed(key); } @@ -3496,31 +3488,15 @@ void Avatar::lockToWall() if (dsq->game->isPaused()) return; TileVector t(position); - TileVector myTile = t; - // 3 + 4 - // 4 + 5 Vector m = vel; m.setLength2D(3); t.x += int(m.x); t.y += int(m.y); - m.setLength2D(2); - TileVector tback = myTile; - tback.x += int(m.x); - tback.y += int(m.y); - - Vector add = m; - add.setLength2D(1); - TileVector tnext = myTile; - tnext.x += int(add.x); - tnext.y += int(add.y); - bool good = true; if (!dsq->game->isObstructed(t)) { - int tried = 0; -//tryAgain: - while(1) + do { TileVector test; @@ -3572,46 +3548,23 @@ void Avatar::lockToWall() t = test; break; } - tried++; - //if (tried >= 2) - if (true) - { - good = false; - break; - } - else - { - //debugLog("trying other"); - //t = myTile; - //goto tryAgain; - } + + good = false; } + while(0); } if (dsq->game->getGrid(t)==OT_HURT && isDamageTarget(DT_WALLHURT)) { good = false; } - if (good /*&& dsq->game->)isObstructed(t2, OT_BLACK)*/ /*&& diff.getSquaredLength2D() > sqr(40)*/) + if (good) { wallNormal = dsq->game->getWallNormal(position); bool outOfWaterHit = (!_isUnderWater && !(wallNormal.y < -0.1f)); - if (wallNormal.isZero() ) //|| outOfWaterHit + if (wallNormal.isZero() ) { debugLog("COULD NOT FIND NORMAL, GOING TO BOUNCE"); - if (outOfWaterHit) - { - /* - Animation *anim = skeletalSprite.getCurrentAnimation(); - if (anim && anim->name == "hitGround") - { - } - else - { - skeletalSprite.animate("hitGround"); - } - */ - } return; } else @@ -3648,16 +3601,6 @@ void Avatar::lockToWall() offset.stop(); - Vector goIn; - - TileVector uset; - if (!dsq->game->isObstructed(tnext)) - { - uset = tnext; - } - else - uset = tback; - int tileType = dsq->game->getGrid(t); Vector offdiff = t.worldVector() - position; if (!offdiff.isZero()) @@ -3948,12 +3891,9 @@ Avatar::Avatar() : Entity(), ActionMapper() bursting = false; burst = 1; burstDelay = 0; - ignoreInputDelay = 0; splashDelay = 0; avatar = this; - particleDelay = 0; - swimming = false; debugLog("Avatar 3"); @@ -6558,32 +6498,15 @@ void Avatar::onUpdate(float dt) if (!rolling && !state.backFlip && !flourish) { - bool swimOnBack = false; - if (swimOnBack) + if (addVec.x > 0) { - if (addVec.x > 0) - { - if (isfh()) - flipHorizontal(); - } - if (addVec.x < 0) - { - if (!isfh()) - flipHorizontal(); - } + if (!isfh()) + flipHorizontal(); } - else + if (addVec.x < 0) { - if (addVec.x > 0) - { - if (!isfh()) - flipHorizontal(); - } - if (addVec.x < 0) - { - if (isfh()) - flipHorizontal(); - } + if (isfh()) + flipHorizontal(); } } diff --git a/Aquaria/Avatar.h b/Aquaria/Avatar.h index 3bb6afa..9b922b2 100644 --- a/Aquaria/Avatar.h +++ b/Aquaria/Avatar.h @@ -445,7 +445,6 @@ protected: bool checkWarpAreas(); void toggleZoom(); - float ignoreInputDelay; float splashDelay; //Hair *hair; @@ -453,8 +452,6 @@ protected: void onUpdate(float dt); void onRender(); - float particleDelay; - //float rippleDelay; Quad *glow; bool swimming; @@ -469,8 +466,7 @@ protected: float pushingOffWallEffect; float lockToWallFallTimer; - Vector dodgeVec; - Vector wallPushVec, wallTurnVec; + Vector wallPushVec; diff --git a/Aquaria/CollideEntity.cpp b/Aquaria/CollideEntity.cpp index 2f854c5..7af48c6 100644 --- a/Aquaria/CollideEntity.cpp +++ b/Aquaria/CollideEntity.cpp @@ -29,9 +29,6 @@ CollideEntity::CollideEntity() : Entity() this->canBeTargetedByAvatar = true; weight = 0; bounceAmount = 0.5f; - bounceEntityAmount = 0.5f; - doCusion = false; - friction = 0; this->updateCull = 4000; } @@ -115,56 +112,6 @@ void CollideEntity::updateMovement(float dt) updateVel2(dt); - if (doCusion) - { - Vector push; - TileVector t(position+vel*dt); - if (dsq->game->isObstructed(TileVector(t.x-1, t.y))) - { - push += Vector(1.25,0); - } - if (dsq->game->isObstructed(TileVector(t.x+1, t.y))) - { - push += Vector(-1.25,0); - } - if (dsq->game->isObstructed(TileVector(t.x, t.y-1))) - { - push += Vector(0,1.25); - } - if (dsq->game->isObstructed(TileVector(t.x, t.y+1))) - { - push += Vector(0,-1.25); - } - if (dsq->game->isObstructed(TileVector(t.x-1, t.y-1))) - { - push += Vector(0.5,0.5); - } - if (dsq->game->isObstructed(TileVector(t.x-1, t.y+1))) - { - push += Vector(0.5,-0.5); - } - if (dsq->game->isObstructed(TileVector(t.x+1, t.y-1))) - { - push += Vector(-0.5,0.5); - } - if (dsq->game->isObstructed(TileVector(t.x+1, t.y+1))) - { - push += Vector(-0.5,-0.5); - } - - // cushion - - if (push.x != 0 || push.y != 0) - { - if (vel.getSquaredLength2D() > sqr(10)) - { - push.setLength2D(100 * dt * 60); - push.z = 0; - } - vel += push; - } - } - Vector lastPosition = position; bool underWater = isUnderWater(); @@ -252,16 +199,6 @@ void CollideEntity::updateMovement(float dt) } } - if (collided && friction != 0 && (vel.x != 0 || vel.y != 0)) - { - Vector fric = vel; - fric.setLength2D(-friction); - vel.z = 0; - vel += fric*dt; - } - - //doFriction(dt); - if (!collided && weight != 0) { vel += Vector(0, weight*dt); diff --git a/Aquaria/CollideEntity.h b/Aquaria/CollideEntity.h index 0100aae..b68213f 100644 --- a/Aquaria/CollideEntity.h +++ b/Aquaria/CollideEntity.h @@ -27,9 +27,8 @@ class CollideEntity : public Entity { public: CollideEntity(); - float bounceAmount, bounceEntityAmount; + float bounceAmount; float weight; - Vector collideOffset; void updateMovement(float dt); void entityDied(Entity *e); protected: @@ -37,8 +36,6 @@ protected: void onUpdateFrozen(float dt); virtual void onBounce() {} - float friction; - bool doCusion; void bounce(float ba); }; diff --git a/Aquaria/Entity.h b/Aquaria/Entity.h index ad54317..f99cc59 100644 --- a/Aquaria/Entity.h +++ b/Aquaria/Entity.h @@ -35,13 +35,12 @@ class Path; struct BoneLock { - BoneLock() : entity(0), bone(0), on(false), origRot(0), offRot(0) {} + BoneLock() : entity(0), bone(0), on(false), origRot(0) {} Entity *entity; Bone *bone; Vector localOffset; bool on; float origRot; - float offRot; Vector wallNormal, circleOffset; int collisionMaskIndex; }; diff --git a/Aquaria/ScriptedEntity.cpp b/Aquaria/ScriptedEntity.cpp index 5b6a7fa..61477a8 100644 --- a/Aquaria/ScriptedEntity.cpp +++ b/Aquaria/ScriptedEntity.cpp @@ -38,7 +38,6 @@ ScriptedEntity::ScriptedEntity(const std::string &scriptName, Vector position, E becomeSolidDelay = false; strandSpacing = 10; animKeyFunc = true; - preUpdateFunc = true; //runningActivation = false; setEntityType(et); @@ -120,16 +119,8 @@ void ScriptedEntity::init() if (!script->call("init", this)) luaDebugMsg("init", script->getLastError()); } - //update(0); Entity::init(); - /* - if (script) - { - bool fail=false; - //update(0); - } - */ } void ScriptedEntity::postInit() @@ -257,11 +248,6 @@ void ScriptedEntity::initStrands(int num, int segs, int dist, int strandSpacing, strands.resize(num); for (int i = 0; i < strands.size(); i++) { - /* - int sz = 5; - if (i == 0 || i == strands.size()-1) - sz = 4; - */ strands[i] = new Strand(position, segs, dist); strands[i]->color = color; dsq->game->addRenderObject(strands[i], this->layer); @@ -269,113 +255,32 @@ void ScriptedEntity::initStrands(int num, int segs, int dist, int strandSpacing, updateStrands(0); } -/* -// write this if/when needed, set all strands to color (with lerp) -void ScriptedEntity::setStrandsColor(const Vector &color, float time) -{ - -} -*/ - void ScriptedEntity::onAlwaysUpdate(float dt) { Entity::onAlwaysUpdate(dt); -// debugLog("calling updateStrands"); + updateStrands(dt); - //HACK: this would be better in base Entity - - /* - if (frozenTimer) - { - } - */ - if (!isEntityDead() && getState() != STATE_DEAD && getState() != STATE_DEATHSCENE && isPresent()) { - const bool useEV=false; - - if (useEV) - { - int mov = getv(EV_MOVEMENT); - if (mov && frozenTimer) - { - doFriction(dt, 50); - } - else - { - // don't update friction if we're in a bubble. - int fric = getv(EV_FRICTION); - if (fric) - { - doFriction(dt, fric); - } - } - - switch (mov) - { - case 1: - updateMovement(dt); - break; - case 2: - updateCurrents(dt); - updateMovement(dt); - break; - } - - if (mov) - { - if (hair) - { - setHairHeadPosition(position); - updateHair(dt); - } - } - - - switch (getv(EV_COLLIDE)) - { - case 1: - if (skeletalSprite.isLoaded()) - dsq->game->handleShotCollisionsSkeletal(this); - else - dsq->game->handleShotCollisions(this); - break; - case 2: - if (skeletalSprite.isLoaded()) - dsq->game->handleShotCollisionsSkeletal(this); - else - dsq->game->handleShotCollisions(this); - - int dmg = getv(EV_TOUCHDMG); - if (frozenTimer > 0) - dmg = 0; - touchAvatarDamage(collideRadius, dmg); - break; - } - } - if (frozenTimer > 0) { pullEmitter.update(dt); - if (!useEV) + doFriction(dt, 50); + updateCurrents(dt); + updateMovement(dt); + + if (hair) { - doFriction(dt, 50); - updateCurrents(dt); - updateMovement(dt); - - if (hair) - { - setHairHeadPosition(position); - updateHair(dt); - } - - if (skeletalSprite.isLoaded()) - dsq->game->handleShotCollisionsSkeletal(this); - else - dsq->game->handleShotCollisions(this); + setHairHeadPosition(position); + updateHair(dt); } + + if (skeletalSprite.isLoaded()) + dsq->game->handleShotCollisionsSkeletal(this); + else + dsq->game->handleShotCollisions(this); } if (isPullable() && !fillGridFromQuad) @@ -387,7 +292,6 @@ void ScriptedEntity::onAlwaysUpdate(float dt) crushDelay = 0.2; doCrush = true; } - //if ((dsq->game->avatar->position - this->position).getSquaredLength2D() < sqr(collideRadius + dsq->game->avatar->collideRadius)) FOR_ENTITIES(i) { Entity *e = *i; @@ -397,9 +301,6 @@ void ScriptedEntity::onAlwaysUpdate(float dt) { if (this->isEntityProperty(EP_BLOCKER) && doCrush) { - //bool doit = !vel.isLength2DIn(200) || (e->position.y > position.y && vel.y > 0); - /*dsq->game->avatar->pullTarget != this ||*/ - /*&& */ bool doit = !vel.isLength2DIn(64) || (e->position.y > position.y && vel.y > 0); if (doit) { @@ -432,11 +333,9 @@ void ScriptedEntity::onAlwaysUpdate(float dt) if (isPullable()) { - //debugLog("movable!"); Entity *followEntity = dsq->game->avatar; if (followEntity && dsq->game->avatar->pullTarget == this) { - //debugLog("followentity!"); Vector dist = followEntity->position - this->position; if (dist.isLength2DIn(followEntity->collideRadius + collideRadius + 16)) { @@ -468,7 +367,6 @@ void ScriptedEntity::onAlwaysUpdate(float dt) if (vel.isLength2DIn(100)) vel = 0; } - //vel = 0; } doCollisionAvoidance(dt, 2, 0.5); } @@ -497,28 +395,8 @@ void ScriptedEntity::updateStrands(float dt) void ScriptedEntity::destroy() { - //debugLog("calling target died"); - CollideEntity::destroy(); - /* - // spring plant might already be destroyed at this point (end of state) - // could add as child? - if (springPlant) - { - //springPlant->life = 0.1; - springPlant->alpha = 0; - } - */ - /* - if (hair) - { - //dsq->removeRenderObject(hair, DESTROY_RENDER_OBJECT); - dsq->game->removeRenderObject(hair); - hair->destroy(); - delete hair; - hair = 0; - } - */ + if (script) { dsq->scriptInterface.closeScript(script); @@ -552,14 +430,9 @@ void ScriptedEntity::startPull() debugLog("HERE!"); if (isEntityProperty(EP_BLOCKER)) { - //debugLog("property set!"); fillGridFromQuad = false; dsq->game->reconstructEntityGrid(); } - else - { - //debugLog("property not set!"); - } pullEmitter.load("Pulled"); pullEmitter.start(); @@ -603,21 +476,8 @@ void ScriptedEntity::onUpdate(float dt) { BBGE_PROF(ScriptedEntity_onUpdate); - /* - if (script && preUpdateFunc) - { - if (!script->call("preUpdate", this, dt)) - { - debugLog(name + " : preUpdate : " + script->getLastError()); - preUpdateFunc = false; - } - } - */ - CollideEntity::onUpdate(dt); - //updateStrands(dt); - if (becomeSolidDelay) { if (vel.isLength2DIn(5)) @@ -659,15 +519,6 @@ void ScriptedEntity::onUpdate(float dt) updateSegments(position, reverseSegments); updateAlpha(alpha.x); } - - /* - //HACK: if this is wanted (to support moving placed entities), then - // springPlant has to notify ScriptedEntity when it is deleted / pulled out - if (springPlant) - { - springPlant->position = this->position; - } - */ } void ScriptedEntity::resetTimer(float t) @@ -720,25 +571,14 @@ bool ScriptedEntity::damage(const DamageData &d) if (!script->call("damage", this, d.attacker, d.bone, int(d.damageType), d.damage, d.hitPos.x, d.hitPos.y, d.shot, &doDefault)) { debugLog(name + ": damage function failed"); - //debugLog(this->name + " : " + script->getLastError() + " hit"); - } - else - { - /* - std::ostringstream os; - os << "doDefault: " << doDefault; - debugLog(os.str()); - */ } } if (doDefault) { - //debugLog("doing default damage"); return Entity::damage(d); } - //debugLog("not doing default damage"); return false; } @@ -835,24 +675,6 @@ void ScriptedEntity::activate() { if (runningActivation) return; Entity::activate(); - /* - if (dsq->game->avatar) - { - Avatar *a = dsq->game->avatar; - if (a->position.x < this->position.x) - { - if (!a->isFlippedHorizontal()) - a->flipHorizontal(); - } - else - { - if (a->isFlippedHorizontal()) - a->flipHorizontal(); - } - if (getEntityType() == ET_NEUTRAL) - flipToTarget(dsq->game->avatar->position); - } - */ runningActivation = true; if (script) @@ -940,15 +762,6 @@ void ScriptedEntity::onEnterState(int action) strands.clear(); // BASE ENTITY CLASS WILL HANDLE CLEANING UP HAIR - /* - if (hair) - { - hair->setLife(1.0); - hair->setDecayRate(10); - hair->fadeAlphaWithLife = true; - hair = 0; - } - */ break; } } diff --git a/Aquaria/ScriptedEntity.h b/Aquaria/ScriptedEntity.h index 54e94d1..d5bcd37 100644 --- a/Aquaria/ScriptedEntity.h +++ b/Aquaria/ScriptedEntity.h @@ -91,7 +91,7 @@ protected: void luaDebugMsg(const std::string &func, const std::string &msg); float crushDelay; int beforePullMaxSpeed; - bool songNoteFunction, preUpdateFunc; + bool songNoteFunction; bool songNoteDoneFunction; std::vector emitters; bool becomeSolidDelay; From fdae0fe9a4999eeb9f0a0c1540dee71712ccf28c Mon Sep 17 00:00:00 2001 From: fgenesis Date: Wed, 4 Sep 2013 16:09:58 +0200 Subject: [PATCH 11/28] New action: ACTION_PLACE_AVATAR. Add Lua functions: - entity_getBoneLockData() - entity_getWeight() --- Aquaria/DSQ.h | 3 ++- Aquaria/SceneEditor.cpp | 1 + Aquaria/ScriptInterface.cpp | 27 ++++++++++++++++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index ed000ff..4553fdd 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -163,7 +163,8 @@ enum AquariaActions ACTION_TOGGLEWORLDMAPEDITOR , ACTION_LOOK , - ACTION_TOGGLEHELPSCREEN + ACTION_TOGGLEHELPSCREEN, + ACTION_PLACE_AVATAR, }; typedef std::list EntityList; diff --git a/Aquaria/SceneEditor.cpp b/Aquaria/SceneEditor.cpp index cf173fb..56694eb 100644 --- a/Aquaria/SceneEditor.cpp +++ b/Aquaria/SceneEditor.cpp @@ -2338,6 +2338,7 @@ void SceneEditor::removeEntity() void SceneEditor::placeAvatar() { dsq->game->avatar->position = dsq->getGameCursorPosition(); + dsq->game->action(ACTION_PLACE_AVATAR, 0); } void SceneEditor::scaleElementUp() diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 12ed8fc..6b1997b 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -2386,6 +2386,23 @@ luaFunc(entity_getBoneLockEntity) luaReturnPtr(ent); } +luaFunc(entity_getBoneLockData) +{ + Entity *e = entity(L); + if (!e) + luaReturnNil(); + BoneLock b = *e->getBoneLock(); // always safe to deref + + lua_pushboolean(L, b.on); + luaPushPointer(L, b.bone); + lua_pushnumber(L, b.origRot); + lua_pushnumber(L, b.wallNormal.x); + lua_pushnumber(L, b.wallNormal.y); + lua_pushnumber(L, b.localOffset.x); + lua_pushnumber(L, b.localOffset.y); + return 7; +} + luaFunc(entity_ensureLimit) { Entity *e = entity(L); @@ -5591,7 +5608,7 @@ luaFunc(entity_setBounce) { CollideEntity *e = collideEntity(L); if (e) - e->bounceAmount = e->bounceEntityAmount = lua_tonumber(L, 2); + e->bounceAmount = lua_tonumber(L, 2); luaReturnNil(); } @@ -7819,6 +7836,12 @@ luaFunc(entity_setWeight) luaReturnNil(); } +luaFunc(entity_getWeight) +{ + CollideEntity *e = collideEntity(L); + luaReturnNum(e ? e->weight : 0.0f); +} + luaFunc(pickupGem) { dsq->continuity.pickupGem(getString(L), !getBool(L, 2)); @@ -8488,6 +8511,7 @@ static const struct { luaRegister(entity_addIgnoreShotDamageType), luaRegister(entity_ensureLimit), luaRegister(entity_getBoneLockEntity), + luaRegister(entity_getBoneLockData), luaRegister(entity_setRidingPosition), luaRegister(entity_setRidingData), @@ -8626,6 +8650,7 @@ static const struct { luaRegister(createEntity), luaRegister(entity_setWeight), + luaRegister(entity_getWeight), luaRegister(entity_setActivationType), From 4d7af56b95f159a2e95ea83524827f2e550b0be8 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Tue, 24 Sep 2013 16:05:05 +0200 Subject: [PATCH 12/28] Animation editor: Add D, Shift+D, Ctrl+Shift+D key combos to flip bone rotation. --- Aquaria/AnimationEditor.cpp | 53 +++++++++++++++++++++++++++++++++++++ Aquaria/States.h | 1 + 2 files changed, 54 insertions(+) diff --git a/Aquaria/AnimationEditor.cpp b/Aquaria/AnimationEditor.cpp index 105c094..110fea3 100644 --- a/Aquaria/AnimationEditor.cpp +++ b/Aquaria/AnimationEditor.cpp @@ -263,6 +263,7 @@ void AnimationEditor::applyState() addAction(MakeFunctionEvent(AnimationEditor, clearRot), KEY_R, 0); addAction(MakeFunctionEvent(AnimationEditor, clearPos), KEY_P, 0); + addAction(MakeFunctionEvent(AnimationEditor, flipRot), KEY_D, 0); addAction(MakeFunctionEvent(AnimationEditor, toggleHideBone), KEY_N, 0); addAction(MakeFunctionEvent(AnimationEditor, copy), KEY_C, 0); addAction(MakeFunctionEvent(AnimationEditor, paste), KEY_V, 0); @@ -1155,6 +1156,58 @@ void AnimationEditor::clearRot() } } +void AnimationEditor::flipRot() +{ + if (dsq->isNested()) return; + + updateEditingBone(); + if (editingBone) + { + if (!core->getShiftState()) + { + BoneKeyframe *b = editSprite->getCurrentAnimation()->getKeyframe(currentKey)->getBoneKeyframe(editingBone->boneIdx); + if (b) + { + b->rot = -b->rot; + } + } + else + { + BoneKeyframe *bcur = editSprite->getCurrentAnimation()->getKeyframe(currentKey)->getBoneKeyframe(editingBone->boneIdx); + if (bcur) + { + int rotdiff = editingBone->rotation.z - bcur->rot; + if (!core->getCtrlState()) + { + for (int i = 0; i < editSprite->getCurrentAnimation()->getNumKeyframes(); ++i) + { + BoneKeyframe *b = editSprite->getCurrentAnimation()->getKeyframe(i)->getBoneKeyframe(editingBone->boneIdx); + if (b) + { + b->rot = -b->rot; + } + } + } + else + { + // all bones in all anims mode + for (int a = 0; a < editSprite->animations.size(); ++a) + { + for (int i = 0; i < editSprite->animations[a].getNumKeyframes(); ++i) + { + BoneKeyframe *b = editSprite->animations[a].getKeyframe(i)->getBoneKeyframe(editingBone->boneIdx); + if (b) + { + b->rot = -b->rot; + } + } + } + } + } + } + } +} + void AnimationEditor::clearPos() { if (dsq->isNested()) return; diff --git a/Aquaria/States.h b/Aquaria/States.h index 080738a..a662a53 100644 --- a/Aquaria/States.h +++ b/Aquaria/States.h @@ -189,6 +189,7 @@ public: void clearRot(); void clearPos(); + void flipRot(); void cycleLerpType(); void toggleHideBone(); From ab74abe903c836833a41872ec3d597cc49e13588 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Tue, 24 Sep 2013 16:54:43 +0200 Subject: [PATCH 13/28] Fix some SceneEditor crashes/quirks and remove some dead code in the process. --- Aquaria/Game.h | 14 -- Aquaria/SceneEditor.cpp | 462 ++++------------------------------------ 2 files changed, 47 insertions(+), 429 deletions(-) diff --git a/Aquaria/Game.h b/Aquaria/Game.h index db33fa1..ed6aa79 100644 --- a/Aquaria/Game.h +++ b/Aquaria/Game.h @@ -341,12 +341,6 @@ enum EditorStates ES_MAX }; -enum SelectionType -{ - ST_SINGLE =0, - ST_MULTIPLE , - ST_MAX -}; #endif class EntityClass @@ -444,9 +438,6 @@ public: EditTypes editType; EditorStates state; - Quad *target; - - Element *getElementAtCursor(); Entity *getEntityAtCursor(); @@ -459,7 +450,6 @@ public: Element *editingElement; Entity *editingEntity; Path *editingPath; - SelectionType selectionType; void toggleWarpAreaRender(); int selectedIdx; @@ -521,19 +511,15 @@ protected: void editModeElements(); void editModeEntities(); void editModePaths(); - int selectedType, possibleSelectedType; void deleteSelected(); void cloneSelectedElement(); - void cloneSelectedElementInput(); void enterScaleState(); void enterRotateState(); void enterMoveState(); Vector oldPosition, oldRotation, oldScale, cursorOffset; - RenderObject *getSelectedRenderObject(); - Entity *movingEntity; void updateDrawingWarpArea(char c, int k); char drawingWarpArea; diff --git a/Aquaria/SceneEditor.cpp b/Aquaria/SceneEditor.cpp index 56694eb..739179b 100644 --- a/Aquaria/SceneEditor.cpp +++ b/Aquaria/SceneEditor.cpp @@ -574,20 +574,12 @@ void SceneEditor::init() selectedElements.clear(); autoSaveTimer = 0; skinMinX = skinMinY = skinMaxX = skinMaxY = -1; - selectionType = ST_SINGLE; editingElement = 0; editingEntity = 0; pathRender = new PathRender(); core->getTopStateData()->addRenderObject(pathRender, LR_DEBUG_TEXT); pathRender->alpha = 0; - selectedType = -1; - possibleSelectedType = -1; - - target = new Quad; - //target->setTexture("target"); - core->getTopStateData()->addRenderObject(target, LR_HUD); - target->alpha = 0; editType = ET_ELEMENTS; state = ES_SELECTING; drawingWarpArea = 'N'; @@ -1026,7 +1018,6 @@ void SceneEditor::moveToBack() void SceneEditor::editModeElements() { selectedIdx = -1; - target->alpha.interpolateTo(0, 0.5); editType = ET_ELEMENTS; if (curElement < dsq->game->elementTemplates.size()) { @@ -1035,6 +1026,8 @@ void SceneEditor::editModeElements() } placer->alpha = 0.5; pathRender->alpha = 0; + editingEntity = NULL; + editingPath = NULL; } void SceneEditor::editModeEntities() @@ -1048,15 +1041,20 @@ void SceneEditor::editModeEntities() placer->setTexture(selectedEntity.prevGfx); placer->alpha = 0.5; pathRender->alpha = 0; + selectedElements.clear(); + editingElement = NULL; + editingPath = NULL; } void SceneEditor::editModePaths() { selectedIdx = -1; - target->alpha.interpolateTo(0, 0.5); editType = ET_PATHS; placer->alpha = 0; pathRender->alpha = 0.5; + selectedElements.clear(); + editingElement = NULL; + editingEntity = NULL; } Element *SceneEditor::getElementAtCursor() @@ -1128,23 +1126,6 @@ void SceneEditor::deleteSelected() editingElement = 0; dsq->game->reconstructGrid(); } - /* - RenderObject *r = getSelectedRenderObject(); - if (r) - { - if (dynamic_cast(r)) - { - deleteSelectedElement(); - } - Entity *ent = 0; - if (ent=dynamic_cast(r)) - { - dsq->game->removeEntity(ent); - //removeEntity(); - } - selectedIdx = -1; - } - */ } else if (editType == ET_ENTITIES) { @@ -1218,23 +1199,6 @@ void SceneEditor::updateSaveFileEnemyPosition(Entity *ent) } -RenderObject *SceneEditor::getSelectedRenderObject() -{ - if (editType == ET_ELEMENTS) - { - if (selectedIdx > -1) - { - if (selectedType == 0) - return dsq->getElement(selectedIdx); - /* - else if (selectedType == 1) - return dsq->entities[selectedIdx]; - */ - } - } - return 0; -} - void SceneEditor::checkForRebuild() { if (editType == ET_ELEMENTS && state != ES_SELECTING && !selectedElements.empty()) @@ -1276,14 +1240,6 @@ void SceneEditor::exitMoveState() void SceneEditor::enterMoveState() { - /* - if (editType == ET_ELEMENTS && state == ES_SELECTING && selectedIdx > -1) - { - state = ES_MOVING; - oldPosition = getSelectedRenderObject()->position; - cursorOffset = getSelectedRenderObject()->position - dsq->getGameCursorPosition(); - } - */ if (state != ES_SELECTING) return; state = ES_MOVING; if (editType == ET_ELEMENTS) @@ -1324,16 +1280,6 @@ void SceneEditor::enterMoveState() void SceneEditor::enterRotateState() { - /* - if (editType == ET_ELEMENTS && state == ES_SELECTING && selectedIdx > -1) - { - state = ES_ROTATING; - oldRotation = getSelectedRenderObject()->rotation; - //cursorOffset = getSelectedRenderObject()->position - dsq->getGameCursorPosition(); - //cursorOffset = Vector(0,0); - cursorOffset = dsq->getGameCursorPosition(); - } - */ if (state != ES_SELECTING) return; if (editType == ET_ENTITIES) { @@ -1365,8 +1311,6 @@ void SceneEditor::enterRotateState() { state = ES_ROTATING; oldRotation = editingElement->rotation; - //cursorOffset = getSelectedRenderObject()->position - dsq->getGameCursorPosition(); - //cursorOffset = Vector(0,0); cursorOffset = dsq->getGameCursorPosition(); } } @@ -1374,15 +1318,6 @@ void SceneEditor::enterRotateState() void SceneEditor::enterScaleState() { - /* - if (editType == ET_ELEMENTS && state == ES_SELECTING && selectedIdx > -1) - { - state = ES_SCALING; - oldScale = getSelectedRenderObject()->scale; - //cursorOffset = getSelectedRenderObject()->position - dsq->getGameCursorPosition(); - cursorOffset = dsq->getGameCursorPosition(); - } - */ if (state != ES_SELECTING) return; if (editType == ET_ELEMENTS) { @@ -1523,41 +1458,11 @@ void SceneEditor::mouseButtonRightUp() //dsq->game->reconstructGrid(); } -/* -void SceneEditor::toggleElementFlag1() -{ - if (editingElement) - { - editingElement->setFlag(""); - } -} - -void SceneEditor::toggleElementFlag2() -{ -} - -void SceneEditor::toggleElementFlag3() -{ -} - -void SceneEditor::toggleElementFlag4() -{ -} - -void SceneEditor::toggleElementFlag5() -{ -} -*/ void SceneEditor::toggleElementSolid() { if (editingElement) { - /* - TileVector t(editingElement->position); - editingElement->position = t.worldVector(); - */ - switch(editingElement->elementFlag) { default: @@ -1623,35 +1528,6 @@ void SceneEditor::mouseButtonLeft() enterMoveState(); } } - /* - if (!selectedElements.empty()) - { - enterMoveState(); - } - */ - /* - if (state == ES_MOVING || state == ES_ROTATING || state == ES_SCALING) - { - if (selectedIdx != -1) - { - if (selectedType == 1) - { - RenderObject *r = getSelectedRenderObject(); - Entity *e = dynamic_cast(r); - if (e) - { - updateSaveFileEnemyPosition(e); - } - } - } - state = ES_SELECTING; - //selectedIdx = -1; - } - else if (state == ES_SELECTING) - { - placeElement(); - } - */ } else if (editType == ET_ENTITIES) { @@ -1685,29 +1561,6 @@ void SceneEditor::mouseButtonLeft() } } } - /* - else if (selectedIdx != -1) - { - if (selectedIdx >= 0 && selectedIdx < dsq->game->getNumPaths()) - { - Path *p = dsq->game->getPath(selectedIdx); - PathNode n; - n.position = dsq->getGameCursorPosition(); - p->nodes.push_back(n); - } - } - else if (selectedIdx != -1) - { - if (selectedIdx >= 0 && selectedIdx < dsq->game->getNumPaths()) - { - Path *p = dsq->game->getPath(selectedIdx); - p->nodes[selectedNode] = - PathNode n; - n.position = dsq->getGameCursorPosition(); - p->nodes.push_back(n); - } - } - */ } } @@ -1746,27 +1599,6 @@ void SceneEditor::mouseButtonRight() else enterRotateState(); } - /* - switch(state) - { - case ES_SELECTING: - selectedType = possibleSelectedType; - selectedIdx = possibleSelectedIdx; - break; - case ES_MOVING: - getSelectedRenderObject()->position = oldPosition; - state = ES_SELECTING; - break; - case ES_ROTATING: - getSelectedRenderObject()->rotation = oldRotation; - state = ES_SELECTING; - break; - case ES_SCALING: - getSelectedRenderObject()->scale = oldScale; - state = ES_SELECTING; - break; - } - */ } if (editType == ET_ELEMENTS && state == ES_MOVING) { @@ -1875,11 +1707,6 @@ void SceneEditor::skinLevel(pngRawInfo *png, int minX, int minY, int maxX, int m { e->safeKill(); deleteElements.push_back(e); - /* - e->setLife(0.1); - e->setDecayRate(1); - deleteElements.push_back(e); - */ } } for (i = 0; i < deleteElements.size(); i++) @@ -2260,14 +2087,6 @@ void SceneEditor::generateLevel() } dsq->game->addObsRow(rows[i].x1/TILE_SIZE, rows[i].y/TILE_SIZE, w/TILE_SIZE); - /* - BoxElement *box = new BoxElement(w,h); - - box->position = Vector(rows[i].x1 + int(w/2), useY); - box->position.z = boxElementZ; - dsq->game->addRenderObject(box, BLACKGROUND); - dsq->elements.push_back(box); - */ } dsq->game->reconstructGrid(true); @@ -2358,6 +2177,9 @@ void SceneEditor::scaleElement1() void SceneEditor::flipElementHorz() { + if (editType != ET_ELEMENTS) + return; + if (editingElement) editingElement->flipHorizontal(); else @@ -2366,6 +2188,9 @@ void SceneEditor::flipElementHorz() void SceneEditor::flipElementVert() { + if (editType != ET_ELEMENTS) + return; + if (editingElement) editingElement->flipVertical(); else @@ -2687,8 +2512,6 @@ void prevEntityPage() createEntityPage(); } -//page = game->entityGroups.begin(); - void SceneEditor::selectEntityFromGroups() { createEntityPage(); @@ -2697,24 +2520,11 @@ void SceneEditor::selectEntityFromGroups() se_changedEntityType = false; editType = ET_SELECTENTITY; - - //bool done = false; - //bool mbrd = false; bool mbld = false; bool ld = false, rd = false; ld = core->getKeyState(KEY_E); while (!se_changedEntityType) { - /* - if (core->mouse.buttons.right && !mbrd) - mbrd = true; - else if (!core->mouse.buttons.right && mbrd) - { - mbrd = false; - nextEntityPage(); - } - */ - if (core->mouse.buttons.left && !mbld) mbld = true; else if (!core->mouse.buttons.left && mbld) @@ -2831,26 +2641,7 @@ void SceneEditor::nextElement() return; } - if (editType == ET_ENTITIES) - { - /* - if (editingEntity) - { - // swap entity type up (somehow) - - } - else - { - curEntity++; - - if (curEntity >= dsq->game->entityTypeList.size()) - curEntity = 0; - - updateEntityPlacer(); - } - */ - } - else if (editType == ET_ELEMENTS) + if (editType == ET_ELEMENTS) { if (dsq->game->elementTemplates.empty()) return; if (core->getCtrlState()) @@ -2888,7 +2679,6 @@ void SceneEditor::nextElement() if (dsq->game->elementTemplates[curElement].idx < 1024) { - //int idx = dsq->game->elementTemplates[curElement].idx; placer->setTexture(dsq->game->elementTemplates[curElement].gfx); } else @@ -2912,28 +2702,8 @@ void SceneEditor::prevElement() return; } } - if (editType == ET_ENTITIES) - { - /* - if (editingEntity) - { - // swap entity type up (somehow) - } - else - { - curEntity--; - if (curEntity < 0) - curEntity = dsq->game->entityTypeList.size()-1; - - updateEntityPlacer(); - - - //dsq->game->entityTypeList - } - */ - } - else if (editType == ET_ELEMENTS) + if (editType == ET_ELEMENTS) { if (dsq->game->elementTemplates.empty()) return; if (!selectedElements.empty()) @@ -2967,7 +2737,6 @@ void SceneEditor::doPrevElement() if (dsq->game->elementTemplates[curElement].idx < 1024) { - //int idx = dsq->game->elementTemplates[curElement].idx; placer->setTexture(dsq->game->elementTemplates[curElement].gfx); } else @@ -2997,29 +2766,6 @@ void SceneEditor::moveLayer() } } } - /* - int realLayer1 = LR_ELEMENTS1 + fromLayer, realLayer2 = LR_ELEMENTS1 + toLayer; - std::vector move; - for (int i = 0; i < dsq->renderObjectLayers[realLayer1].renderObjects.size(); i++) - { - RenderObject *r = dsq->renderObjectLayers[realLayer1].renderObjects[i]; - if (r) - { - move.push_back(r); - core->removeRenderObject(r, Core::DO_NOT_DESTROY_RENDER_OBJECT); - //dsq->renderObjectLayers[realLayer1].renderObjects[i] = 0; - } - } - for (int i = 0; i < move.size(); i++) - { - RenderObject *r = move[i]; - if (r) - { - r->layer = realLayer2; - dsq->addRenderObject(r, realLayer2); - } - } - */ } } @@ -3070,8 +2816,6 @@ void SceneEditor::placeElement() { if (!core->getShiftState() && !core->getKeyState(KEY_LALT) && !drawingBox) { - //errorLog("placeElement"); - dsq->game->createElement(dsq->game->elementTemplates[curElement].idx, placer->position, bgLayer, placer); updateText(); dsq->game->reconstructGrid(); @@ -3104,29 +2848,10 @@ void SceneEditor::placeElement() { p->addNode(selectedNode); } - /* - if (selectedIdx >= 0 && selectedIdx < dsq->game->getNumPaths()) - { - Path *p = dsq->game->getPath(selectedIdx); - PathNode n; - n.position = dsq->getGameCursorPosition(); - p->nodes.push_back(n); - } - */ } } } -void SceneEditor::cloneSelectedElementInput() -{ - /* - if (core->getShiftState()) - { - cloneSelectedElement(); - } - */ -} - void SceneEditor::cloneSelectedElement() { if (editType == ET_ELEMENTS) @@ -3180,15 +2905,6 @@ void SceneEditor::cloneSelectedElement() newp->init(); } } - - /* - if (selectedIdx > -1) - { - Element *e1 = dsq->elements[selectedIdx]; - Element *e = dsq->game->createElement(e1->templateIdx, placer->position, e1->layer-LR_ELEMENTS1, getSelectedRenderObject()); - selectedIdx = dsq->elements.size()-1; - } - */ } void SceneEditor::shutdown() @@ -3265,7 +2981,6 @@ void SceneEditor::toggle(bool on) text->alpha.interpolateTo(0, 0.2); placer->alpha.interpolateTo(0, 0.2); //core->flags.unset(CF_CLEARBUFFERS); - target->alpha = 0; dsq->darkLayer.toggle(true); dsq->game->rebuildElementUpdateList(); @@ -3400,14 +3115,6 @@ void SceneEditor::endDrawingWarpArea(char c) a.sceneName = dsq->getUserInputString("Enter map to warp to"); a.spawnOffset = dsq->getUserInputDirection("Enter warp direction"); dsq->game->warpAreas.push_back(a); - /* - BoxElement *boxElement = new BoxElement(boxPromo->width.getValue(), boxPromo->height.getValue()); - boxElement->position = boxPromo->position; - boxElement->position.z = boxElementZ; - dsq->game->addRenderObject(boxElement, BLACKGROUND); - dsq->elements.push_back(boxElement); - dsq->game->reconstructGrid(); - */ } } } @@ -3482,9 +3189,6 @@ void SceneEditor::update(float dt) Vector p = Vector(cursorTile.x*TILE_SIZE+TILE_SIZE/2, cursorTile.y*TILE_SIZE+TILE_SIZE/2); placer->position = p; - - //selectedIdx = idx; - int camSpeed = 500/zoom.x; if (core->getShiftState()) camSpeed = 5000/zoom.x; @@ -3533,19 +3237,6 @@ void SceneEditor::update(float dt) dsq->cameraPos.y += mouseY/oldZoom.y - mouseY/zoom.y; } - /* - for (int i = 0; i < dsq->elements.size(); i++) - { - //dsq->elements[i]->flags.unset(RO_RENDERBORDERS); - dsq->elements[i]->renderBorders = false; - } - RenderObject *r; - if (r = getSelectedRenderObject()) - { - //r->flags.set(RO_RENDERBORDERS); - r->renderBorders = true; - } - */ if (this->editType == ET_PATHS) { switch(state) @@ -3574,23 +3265,26 @@ void SceneEditor::update(float dt) break; case ES_SCALING: { - float factor = 1; - Vector add = Vector((dsq->getGameCursorPosition().x - cursorOffset.x)*factor, - (dsq->getGameCursorPosition().y - cursorOffset.y)*factor); - //editingElement->scale=oldScale + add; - Vector sz = oldScale + add; - if (sz.x < 32) - sz.x = 32; - if (sz.y < 32) - sz.y = 32; - editingPath->rect.x1 = -sz.x/2; - editingPath->rect.x2 = sz.x/2; - editingPath->rect.y1 = -sz.y/2; - editingPath->rect.y2 = sz.y/2; + if (editingPath) + { + float factor = 1; + Vector add = Vector((dsq->getGameCursorPosition().x - cursorOffset.x)*factor, + (dsq->getGameCursorPosition().y - cursorOffset.y)*factor); + Vector sz = oldScale + add; + if (sz.x < 32) + sz.x = 32; + if (sz.y < 32) + sz.y = 32; + editingPath->rect.x1 = -sz.x/2; + editingPath->rect.x2 = sz.x/2; + editingPath->rect.y1 = -sz.y/2; + editingPath->rect.y2 = sz.y/2; + } } break; case ES_MOVING: - dsq->game->getPath(selectedIdx)->nodes[selectedNode].position = dsq->getGameCursorPosition() + cursorOffset; + if (selectedIdx >= 0) + dsq->game->getPath(selectedIdx)->nodes[selectedNode].position = dsq->getGameCursorPosition() + cursorOffset; break; } } @@ -3599,27 +3293,24 @@ void SceneEditor::update(float dt) switch(state) { case ES_MOVING: - editingEntity->position = dsq->getGameCursorPosition() + cursorOffset; - /* - if (core->getShiftState()) - { - TileVector t(getSelectedRenderObject()->position); - getSelectedRenderObject()->position = t.worldVector(); - } - */ + if (editingEntity) + editingEntity->position = dsq->getGameCursorPosition() + cursorOffset; break; case ES_ROTATING: { - float add = (dsq->getGameCursorPosition().x - cursorOffset.x)/2.4f; - if (core->getCtrlState()) + if (editingEntity) { - int a = (oldRotation.z + add)/45; - add = a * 45; - editingEntity->rotation.z = add; - } - else - { - editingEntity->rotation.z = oldRotation.z + add; + float add = (dsq->getGameCursorPosition().x - cursorOffset.x)/2.4f; + if (core->getCtrlState()) + { + int a = (oldRotation.z + add)/45; + add = a * 45; + editingEntity->rotation.z = add; + } + else + { + editingEntity->rotation.z = oldRotation.z + add; + } } } } @@ -3640,37 +3331,12 @@ void SceneEditor::update(float dt) { closest = len; idx = i; - possibleSelectedType = 0; } } - - /* - FOR_ENTITIES(i) - { - Entity *e = *i; - Vector dist = e->position - dsq->getGameCursorPosition(); - int len = dist.getSquaredLength2D(); - if ((len < closest || closest == -1)) - { - closest = len; - idx = i; - possibleSelectedType = 1; - } - } - - possibleSelectedIdx = idx; - */ } break; case ES_MOVING: updateSelectedElementPosition(dsq->getGameCursorPosition() - cursorOffset); - /* - if (core->getShiftState()) - { - TileVector t(getSelectedRenderObject()->position); - getSelectedRenderObject()->position = t.worldVector(); - } - */ break; case ES_ROTATING: { @@ -3808,20 +3474,6 @@ void SceneEditor::update(float dt) break; } } - RenderObject *r = getSelectedRenderObject(); - if (r) - { - target->position = r->position; - target->alpha = 1; - } - else - target->alpha = 0; - /* - if (movingEntity) - { - movingEntity->position = dsq->getGameCursorPosition(); - } - */ } } @@ -3836,16 +3488,6 @@ void SceneEditor::nextEntityType() exitMoveState(); } } - else if (editType == ET_ENTITIES) - { - /* - selectedEntityType++; - if (selectedEntityType>=dsq->game->entityTypeList.size()) - { - selectedEntityType = 0; - } - */ - } else if (editType == ET_SELECTENTITY) { nextEntityPage(); @@ -3863,16 +3505,6 @@ void SceneEditor::prevEntityType() exitMoveState(); } } - else if (editType == ET_ENTITIES) - { - /* - selectedEntityType --; - if (selectedEntityType < 0) - { - selectedEntityType = dsq->game->entityTypeList.size()-1; - } - */ - } else if (editType == ET_SELECTENTITY) { prevEntityPage(); From 6f9063ce6d04d4d9f1c7160a7a5e4a45398a6e3a Mon Sep 17 00:00:00 2001 From: fgenesis Date: Tue, 24 Sep 2013 17:00:06 +0200 Subject: [PATCH 14/28] Map element code refactoring. Allow other entities to influence map elements (EFX_WAVY). Reduce Element memory; as most elements do not have any effect set, this saves more than 50 bytes per element. --- Aquaria/Avatar.cpp | 15 ++- Aquaria/Avatar.h | 1 + Aquaria/DSQ.cpp | 19 +-- Aquaria/DSQ.h | 5 +- Aquaria/Element.cpp | 310 ++++++++++++++++---------------------------- Aquaria/Element.h | 44 +++---- Aquaria/Game.cpp | 6 + Aquaria/Game.h | 3 +- 8 files changed, 163 insertions(+), 240 deletions(-) diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index 805f31c..a44207b 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -1629,7 +1629,7 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF break; } - + elementEffectMult = 1; state.abilityDelay = 0; formAbilityDelay = 0; dsq->continuity.form = form; @@ -1731,6 +1731,7 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF collideRadius = COLLIDE_RADIUS_FISH; setCanLockToWall(false); setCollisionAvoidanceData(COLLIDE_RANGE_FISH, COLLIDE_MOD_FISH); + elementEffectMult = 0.4f; } break; case FORM_SUN: @@ -1780,6 +1781,7 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF setCanLockToWall(false); setCanBurst(false); setDamageTarget(DT_WALLHURT, false); + elementEffectMult = 0; if (onInit) { @@ -4076,6 +4078,7 @@ Avatar::Avatar() : Entity(), ActionMapper() _seeMapMode = SEE_MAP_DEFAULT; blockBackFlip = false; + elementEffectMult = 1; } void Avatar::revert() @@ -7133,6 +7136,16 @@ void Avatar::onUpdate(float dt) if(canCollideWithShots()) dsq->game->handleShotCollisions(this, (activeAura == AURA_SHIELD)); + + + if(!core->particlesPaused && elementEffectMult > 0) + { + ElementUpdateList& elems = dsq->game->elementUpdateList; + for (ElementUpdateList::iterator it = elems.begin(); it != elems.end(); ++it) + { + (*it)->doInteraction(this, elementEffectMult, 16); + } + } } diff --git a/Aquaria/Avatar.h b/Aquaria/Avatar.h index 9b922b2..7b3d315 100644 --- a/Aquaria/Avatar.h +++ b/Aquaria/Avatar.h @@ -346,6 +346,7 @@ public: int leaches; float shieldPoints; + float elementEffectMult; bool blockBackFlip; diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index 207aab8..2dc65dc 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -359,7 +359,7 @@ ElementEffect DSQ::getElementEffectByIndex(int e) return empty; } - +/* Element *DSQ::getSolidElementNear(Vector pos, int rad) { Element *closestE = 0; @@ -376,26 +376,12 @@ Element *DSQ::getSolidElementNear(Vector pos, int rad) } return closestE; } - +*/ Vector DSQ::getCameraCenter() { return cameraPos; //+ Vector(400*(1.0f/core->globalScale.x),300*(1.0f/core->globalScale.x)); } -void DSQ::doScript(const std::string &script) -{ - /* - this->script.loadScriptFile(script); - this->script.run("void main()"); - */ -} - -void DSQ::print(int x, int y, const std::string &text) -{ -// CTextDrawer::GetSingleton().PrintText(x, y, text.c_str()); -} - - void DSQ::centerMessage(const std::string &text, float y, int type) { Vector pos(400,y); @@ -4559,6 +4545,7 @@ void DSQ::onUpdate(float dt) os << dsq->sound->getVolumeString() << std::endl; os << "runInBG: " << core->settings.runInBackground << " nested: " << core->getNestedMains() << std::endl; os << core->globalResolutionScale.x << ", " << core->globalResolutionScale.y << std::endl; + os << "elemu: " << game->elementUpdateList.size() << " elemi: " << game->elementInteractionList.size() << std::endl; os << "Lua mem: " << scriptInterface.gcGetStats() << " KB" << std::endl; cmDebug->setText(os.str()); diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 4553fdd..60d178a 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -1270,10 +1270,7 @@ public: void setTexturePointers(); - void doScript(const std::string &script); - void fade(float alpha, float time); - void print(int x, int y, const std::string &text); void applyParallaxUserSettings(); @@ -1380,7 +1377,7 @@ public: std::string getDialogueFilename(const std::string &f); bool isShakingCamera(); - Element *getSolidElementNear(Vector pos, int rad); + //Element *getSolidElementNear(Vector pos, int rad); std::string languagePack; diff --git a/Aquaria/Element.cpp b/Aquaria/Element.cpp index c4a94ef..9c8cc51 100644 --- a/Aquaria/Element.cpp +++ b/Aquaria/Element.cpp @@ -20,169 +20,150 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Element.h" #include "Game.h" -#include "Avatar.h" + +ElementEffectData::ElementEffectData() + : elementEffectIndex(-1) + , wavyAngleOffset(0) + , wavyMagnitude(0) + , wavyLerpIn(0) + , wavyMin(0) + , wavyMax(0) + , hitPerc(0) + , effectMult(0) + , wavyWaving(false) + , wavyFlip(false) + , touching(false) + , elementEffectType(EFX_NONE) +{ +} Element::Element() : Quad() { elementFlag = EF_NONE; - wavyFlip = false; - elementEffectIndex = -1; elementActive = true; bgLayer = 0; - - wavyAngleOffset=0; - wavyMagnitude=0; - wavyLerpIn=0; - wavyWaving=false; - wavyFlip=false; - - elementEffectType = 0; - wavyRadius = 0; - wavyMin = 0; - wavyMax = 0; templateIdx = -1; + eff = NULL; setStatic(true); } -void Element::wavyPull(int to, int from, float dt) +void Element::ensureEffectData() { - Vector diff = wavy[to] - wavy[from]; - if (!diff.isZero()) + if (!eff) + eff = new ElementEffectData; +} + +void Element::freeEffectData() +{ + if (eff) { - diff.capLength2D(wavyMax); - if (diff.isLength2DIn(wavyMin)) - { - diff.setLength2D(wavyMin); - } - wavy[to] = wavy[from] + diff; + delete eff; + eff = NULL; } } +void Element::doInteraction(Entity *ent, float mult, float touchWidth) +{ + ElementEffectData *eff = this->eff; + Vector pos = position; + pos.y -= (height*scale.y)/2; + + float hitPerc=0; + Vector p = ent->position; + if (p.x > position.x-touchWidth && p.x < position.x+touchWidth) + { + float h2 = (height*scale.y)/2.0f; + if (p.y < position.y+h2 && p.y > position.y-h2) + { + eff->touching = true; + eff->wavyWaving = true; + hitPerc = pos.y - p.y; + hitPerc /= float(height*scale.y); + hitPerc = (1.0f-hitPerc)-1.0f; + eff->hitPerc = hitPerc; + eff->touchVel = ent->vel; + eff->effectMult = mult; + return; + } + } + //eff->touchVel = Vector(0, 0); + //eff->hitPerc = 0; + eff->touching = false; +} + void Element::updateEffects(float dt) { - switch (elementEffectType) + switch (eff->elementEffectType) { case EFX_ALPHA: alpha.update(dt); - break; + break; case EFX_WAVY: //debugLog("EXF_WAVY update"); /// check player position { // if a big wavy doesn't work, this is probably why - //if ((position - dsq->game->avatar->position).isLength2DIn(1024)) + //if ((position - ent->position).isLength2DIn(1024)) { - int touchIdx = -1; - Vector pos = position; - pos.y = position.y - (height*scale.y)/2; + ElementEffectData *eff = this->eff; - float hitPerc=0; - Vector p = dsq->game->avatar->position;// + Vector(200,0); - if (p.x > position.x-16 && p.x < position.x+16) + if (eff->touching) { - float h2 = (height*scale.y)/2.0f; - if (p.y < position.y+h2 && p.y > position.y-h2) - { - touchIdx = 0; - hitPerc = pos.y - p.y; - hitPerc /= float(height*scale.y); - hitPerc = (1.0f-hitPerc)-1.0f; - - - //std::cout << "hit!\n"; - /* - std::ostringstream os; - os << "hit perc: " << hitPerc; - debugLog(os.str()); - */ - } - } - /* - for (int i = 0; i < wavy.size()-1; i++) - { - if (isTouchingLine(wavy[0]+pos, wavy[i+1]+pos, dsq->game->avatar->position, wavyRadius)) - { - //wavy[i+1] = dsq->game->avatar->position; - touchIdx = i+1; - break; - } - } - */ - - if (touchIdx != -1) - { - // start pull - wavyWaving = true; - wavyAngleOffset = 0; - float ramp = dsq->game->avatar->vel.getLength2D()/800.0f; + float ramp = eff->touchVel.getLength2D()/800.0f; if (ramp < 0) ramp = 0; if (ramp > 1) ramp = 1; - wavyMagnitude = 100 * ramp + 16; + eff->wavyMagnitude = 100 * ramp + 16; - if (dsq->game->avatar->vel.x < 0) - wavyMagnitude = -wavyMagnitude; + if (eff->touchVel.x < 0) + eff->wavyMagnitude = -eff->wavyMagnitude; - /* - if (hitPerc > 0.35f) - wavyMagnitude = -wavyMagnitude; - */ + eff->wavyAngleOffset = (eff->hitPerc-0.5f)*PI; - wavyAngleOffset = (hitPerc-0.5f)*PI; - - wavySave = wavy; - wavyLerpIn = 0; + eff->wavySave = eff->wavy; + eff->wavyLerpIn = 0; } - if (wavyWaving) + if (eff->wavyWaving) { - /* - float wavyMagnitude = wavyMagnitude; - if (dsq->continuity.form == FORM_FISH) - wavyMagnitude *= 0.1f; - */ - float wavyMagMult = 1; - - if (dsq->continuity.form == FORM_FISH) - wavyMagMult = 0.4; - float spd = PI*1.1f; float magRedSpd = 48; float lerpSpd = 5.0; - for (int i = 0; i < wavy.size(); i++) + float wavySz = float(eff->wavy.size()); + for (int i = 0; i < eff->wavy.size(); i++) { - float weight = float(i)/float(wavy.size()); - if (wavyFlip) + float weight = float(i)/wavySz; + if (eff->wavyFlip) weight = 1.0f-weight; if (weight < 0.125f) weight *= 0.5f; - wavy[i].x = sinf(wavyAngleOffset + (float(i)/float(wavy.size()))*PI)*float(wavyMagnitude*wavyMagMult)*weight; - if (!wavySave.empty()) + eff->wavy[i].x = sinf(eff->wavyAngleOffset + (float(i)/wavySz)*PI)*float(eff->wavyMagnitude*eff->effectMult)*weight; + if (!eff->wavySave.empty()) { - if (wavyLerpIn < 1) - wavy[i].x = wavy[i].x*wavyLerpIn + (wavySave[i].x*(1.0f-wavyLerpIn)); + if (eff->wavyLerpIn < 1) + eff->wavy[i].x = eff->wavy[i].x*eff->wavyLerpIn + (eff->wavySave[i].x*(1.0f-eff->wavyLerpIn)); } } - if (wavyLerpIn < 1) + if (eff->wavyLerpIn < 1) { - wavyLerpIn += dt*lerpSpd; - if (wavyLerpIn > 1) - wavyLerpIn = 1; + eff->wavyLerpIn += dt*lerpSpd; + if (eff->wavyLerpIn > 1) + eff->wavyLerpIn = 1; } - wavyAngleOffset += dt*spd; - if (wavyMagnitude > 0) + eff->wavyAngleOffset += dt*spd; + if (eff->wavyMagnitude > 0) { - wavyMagnitude -= magRedSpd*dt; - if (wavyMagnitude < 0) - wavyMagnitude = 0; + eff->wavyMagnitude -= magRedSpd*dt; + if (eff->wavyMagnitude < 0) + eff->wavyMagnitude = 0; } else { - wavyMagnitude += magRedSpd*dt; - if (wavyMagnitude > 0) - wavyMagnitude = 0; + eff->wavyMagnitude += magRedSpd*dt; + if (eff->wavyMagnitude > 0) + eff->wavyMagnitude = 0; } //std::cout << "setting grid from wav w/ wavyWaving\n"; @@ -194,24 +175,6 @@ void Element::updateEffects(float dt) //std::cout << "not waving"; setGridFromWavy(); } - /* - for (int i = touchIdx; i < wavy.size()-1; i++) - { - wavyPull(i, i+1, dt); - } - for (int i = touchIdx; i >= 0; i--) - { - wavyPull(i, i-1, dt); - } - */ - - // normal down pull - /* - for (int i = 0; i < wavy.size()-1; i++) - { - wavyPull(i, i+1, dt); - } - */ } } break; @@ -224,16 +187,16 @@ void Element::update(float dt) if (!core->particlesPaused) { updateLife(dt); - updateEffects(dt); + if (eff) + updateEffects(dt); if (drawGrid) updateGrid(dt); } - -// updateCullVariables(); } Element::~Element() { + freeEffectData(); } void Element::destroy() @@ -243,7 +206,7 @@ void Element::destroy() int Element::getElementEffectIndex() { - return elementEffectIndex; + return eff ? eff->elementEffectIndex : -1; } void Element::setGridFromWavy() @@ -251,16 +214,18 @@ void Element::setGridFromWavy() if (drawGrid) { //std::cout << "set grid from wavy (" << xDivs << ", " << yDivs << ")\n" - + const float w = float(getWidth()); for (int x = 0; x < xDivs-1; x++) { for (int y = 0; y < yDivs; y++) { - int wavy_y = (yDivs - y)-1; - if (wavy_y < wavy.size()) + const int wavy_y = (yDivs - y)-1; + const float tmp = eff->wavy[wavy_y].x / w; + if (wavy_y < eff->wavy.size()) { - drawGrid[x][y].x = (wavy[wavy_y].x/float(getWidth()) - 0.5f); - drawGrid[x+1][y].x = (wavy[wavy_y].x/float(getWidth()) + 0.5f); + + drawGrid[x][y].x = tmp - 0.5f; + drawGrid[x+1][y].x = tmp + 0.5f; } } } @@ -279,9 +244,9 @@ void Element::setElementEffectByIndex(int eidx) alpha.stop(); alpha = 1; - elementEffectIndex = eidx; - ElementEffect e = dsq->getElementEffectByIndex(eidx); + if(e.type != EFX_NONE) + ensureEffectData(); switch(e.type) { @@ -305,37 +270,32 @@ void Element::setElementEffectByIndex(int eidx) sprintf(buf, "setting wavy segsy: %d radius: %d min: %d max: %d", e.segsy, e.wavy_radius, e.wavy_min, e.wavy_max); debugLog(buf); */ - wavy.resize(e.segsy); + eff->wavy.resize(e.segsy); float bity = float(getHeight())/float(e.segsy); - for (int i = 0; i < wavy.size(); i++) + for (int i = 0; i < eff->wavy.size(); i++) { - wavy[i] = Vector(0, -(i*bity)); + eff->wavy[i] = Vector(0, -(i*bity)); } - //wavySave = wavy; - wavyRadius = e.wavy_radius; - wavyFlip = e.wavy_flip; - wavyMin = bity; - wavyMax = bity*1.2f; - - //wavyRadius = 8; + eff->wavyFlip = e.wavy_flip; + eff->wavyMin = bity; + eff->wavyMax = bity*1.2f; createGrid(2, e.segsy); - setGridFromWavy(); - - //createGrid(8,8); - /* - wavyMin = e.wavy_min; - wavyMax = e.wavy_max; - */ setStatic(false); } break; default: + freeEffectData(); setStatic(true); break; } - elementEffectType = e.type; + + if (eff) + { + eff->elementEffectIndex = eidx; + eff->elementEffectType = e.type; + } } void Element::render() @@ -364,32 +324,8 @@ void Element::render() } #endif - if (this->elementEffectType == EFX_WAVY) - { - //debugLog("rendering efx_wavy"); - } - Quad::render(); - /* - if (!wavy.empty()) - { - - glDisable(GL_BLEND); - Vector pos = position; - pos.y = position.y + (getHeight()*scale.y)/2.0f; - glBegin(GL_LINES); - for (int i = 0; i < wavy.size()-1; i++) - { - glColor4f(1, 0, 0, 1); - glVertex3f(wavy[i].x+pos.x, wavy[i].y+pos.y, 0); - glVertex3f(wavy[i+1].x+pos.x, wavy[i+1].y+pos.y, 0); - } - glEnd(); - glEnable(GL_BLEND); - } - */ - renderBorder = false; } @@ -416,19 +352,3 @@ void Element::fillGrid() } } -// override this functionality as needed -bool Element::canSeeAvatar(Avatar *avatar) -{ - return false; -} - -bool Element::isActive() -{ - return true; -} - -float Element::getSortDepth() -{ - return Quad::getSortDepth() - bgLayer*0.01f; -} - diff --git a/Aquaria/Element.h b/Aquaria/Element.h index e3b156b..c2802c3 100644 --- a/Aquaria/Element.h +++ b/Aquaria/Element.h @@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "../BBGE/Quad.h" -class Avatar; +class Entity; enum ElementFlag @@ -42,50 +42,48 @@ enum ElementFlag */ }; +struct ElementEffectData +{ + ElementEffectData(); + + int elementEffectType; + float wavyAngleOffset, wavyMagnitude, wavyLerpIn; + float wavyMin, wavyMax; + float hitPerc, effectMult; + bool wavyWaving, wavyFlip, touching; + Vector touchVel; + std::vector wavy, wavySave; + int elementEffectIndex; // used by editor only +}; + class Element : public Quad { public: Element(); ~Element(); void destroy(); - //void interact(Interaction::Type interactionType, Avatar *avatar); - bool canSeeAvatar(Avatar *avatar); void update(float dt); - bool isActive(); - //InteractionContainer interactions; int templateIdx; int bgLayer; Element *bgLayerNext; - float getSortDepth(); void render(); - //Flags elementFlags; ElementFlag elementFlag; void fillGrid(); bool isElementActive() { return elementActive; } int getElementEffectIndex(); void setElementEffectByIndex(int e); void setElementActive(bool v) { elementActive = v; } + void doInteraction(Entity *ent, float mult, float touchWidth); protected: + void ensureEffectData(); + void freeEffectData(); void setGridFromWavy(); - float wavyAngleOffset, wavyMagnitude, wavyLerpIn; - bool wavyWaving, wavyFlip; - void wavyPull(int to, int from, float dt); - std::vector wavy, wavySave; - float wavyRadius, wavyMin, wavyMax; + ElementEffectData *eff; + void updateEffects(float dt); - int elementEffectIndex, elementEffectType; + bool elementActive; }; -/* -class BoxElement : public Element -{ -public: - BoxElement(int width, int height); - //bool isOnScreen(); -protected: - int ww,hh; -}; -*/ typedef std::vector ElementContainer; diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index f4a105f..301d1f6 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -5789,6 +5789,7 @@ void Game::rebuildElementUpdateList() dsq->getRenderObjectLayer(i)->update = false; elementUpdateList.clear(); + elementInteractionList.clear(); for (int i = 0; i < dsq->getNumElements(); i++) //for (int i = LR_ELEMENTS1; i <= LR_ELEMENTS8; i++) { @@ -5800,6 +5801,11 @@ void Game::rebuildElementUpdateList() { elementUpdateList.push_back(e); } + ElementEffect ee = dsq->getElementEffectByIndex(e->getElementEffectIndex()); + if(ee.type == EFX_WAVY) + { + elementInteractionList.push_back(e); + } } } } diff --git a/Aquaria/Game.h b/Aquaria/Game.h index ed6aa79..0cdf44f 100644 --- a/Aquaria/Game.h +++ b/Aquaria/Game.h @@ -568,7 +568,7 @@ protected: typedef std::vector QuadList; typedef std::vector QuadArray; -typedef std::list ElementUpdateList; +typedef std::vector ElementUpdateList; // Note: although this is a bitmask, only one of these values may be set at a time! enum ObsType @@ -961,6 +961,7 @@ public: GridRender *gridRender, *gridRender2, *gridRender3, *edgeRender, *gridRenderEnt; void toggleGridRender(); ElementUpdateList elementUpdateList; + ElementUpdateList elementInteractionList; bool invinciblity; From 0df586874d8a556db678f24215c5be8d02686568 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Tue, 24 Sep 2013 17:02:06 +0200 Subject: [PATCH 15/28] Script interface: - Add entity_doElementInteraction() - Add avatar_setElementEffectMult() - Change entity_isUnderWater(): Can now supply an override position. --- Aquaria/ScriptInterface.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 6b1997b..435f921 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -3572,7 +3572,7 @@ luaFunc(entity_isUnderWater) bool b = false; if (e) { - b = e->isUnderWater(); + b = e->isUnderWater(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3))); } luaReturnBool(b); } @@ -5146,6 +5146,31 @@ luaFunc(entity_applySurfaceNormalForce) luaReturnNil(); } +luaFunc(entity_doElementInteraction) +{ + Entity *e = entity(L); + if (e) + { + float mult = lua_tonumber(L, 2); + float touchWidth = lua_tonumber(L, 3); + if (!touchWidth) + touchWidth = 16; + + ElementUpdateList& elems = dsq->game->elementUpdateList; + for (ElementUpdateList::iterator it = elems.begin(); it != elems.end(); ++it) + { + (*it)->doInteraction(e, mult, touchWidth); + } + } + luaReturnNil(); +} + +luaFunc(avatar_setElementEffectMult) +{ + dsq->game->avatar->elementEffectMult = lua_tonumber(L, 1); + luaReturnNil(); +} + luaFunc(flingMonkey) { Entity *e = entity(L); @@ -8636,6 +8661,9 @@ static const struct { luaRegister(entity_adjustPositionBySurfaceNormal), luaRegister(entity_applySurfaceNormalForce), + luaRegister(entity_doElementInteraction), + luaRegister(avatar_setElementEffectMult), + luaRegister(createBeam), luaRegister(beam_setAngle), luaRegister(beam_setDamage), From 358b8d139d8d6a1b028cf0ad0715a20a43c9186a Mon Sep 17 00:00:00 2001 From: fgenesis Date: Tue, 24 Sep 2013 17:25:33 +0200 Subject: [PATCH 16/28] Display build date in version string. --- Aquaria/AquariaCompileConfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Aquaria/AquariaCompileConfig.h b/Aquaria/AquariaCompileConfig.h index 922d212..4dd79e3 100644 --- a/Aquaria/AquariaCompileConfig.h +++ b/Aquaria/AquariaCompileConfig.h @@ -9,7 +9,7 @@ #define AQUARIA_BUILD_CONSOLE 1 #define AQUARIA_BUILD_SCENEEDITOR 1 - #define AQUARIA_CUSTOM_BUILD_ID "" + #define AQUARIA_CUSTOM_BUILD_ID (" Build " __DATE__ " - " __TIME__) // If defined, this is shown instead of "Aquaria vx.x.x ..." on the title screen. //#define AQUARIA_OVERRIDE_VERSION_STRING "Aquaria OSE v1.000" From 36c409e1d436b31b60d55ccf5d8d9103fd7d2220 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sat, 28 Sep 2013 17:21:11 +0200 Subject: [PATCH 17/28] Little things: - Make ACTION_LOOK and ACTION_ROLL available to handle via nodes - Add entity_getPushVec() - Fix typo in beam_setFirer() - Add pull param to addInfluence() - Add entity_getPushDamage() - Add getMouseWheelChange() --- Aquaria/Entity.h | 3 +++ Aquaria/Game.cpp | 5 +++++ Aquaria/ScriptInterface.cpp | 26 +++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Aquaria/Entity.h b/Aquaria/Entity.h index f99cc59..190ad3b 100644 --- a/Aquaria/Entity.h +++ b/Aquaria/Entity.h @@ -495,6 +495,9 @@ public: void updateSoundPosition(); + Vector getPushVec() const { return pushVec; } + float getPushDamage() const { return pushDamage; } + protected: bool calledEntityDied; Path *waterBubble; diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 301d1f6..fcd5252 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -6692,7 +6692,10 @@ void Game::applyState() } if(cookingScript) + { dsq->scriptInterface.closeScript(cookingScript); + cookingScript = NULL; + } if (dsq->mod.isActive()) cookingScript = dsq->scriptInterface.openScript(dsq->mod.getPath() + "scripts/cooking.lua", true); @@ -6913,6 +6916,8 @@ void Game::bindInput() dsq->user.control.actionSet.importAction(this, "Revert", ACTION_REVERT); + dsq->user.control.actionSet.importAction(this, "Look", ACTION_LOOK); + dsq->user.control.actionSet.importAction(this, "Roll", ACTION_ROLL); if (avatar) avatar->bindInput(); diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 435f921..6b413be 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -2332,6 +2332,15 @@ luaFunc(entity_clearVel) } // end extra Entity::vel functions +luaFunc(entity_getPushVec) +{ + Entity *e = entity(L); + Vector v; + if (e) + v = e->getPushVec(); + luaReturnVec2(v.x, v.y); +} + luaFunc(entity_addIgnoreShotDamageType) { Entity *e = entity(L); @@ -4186,7 +4195,7 @@ luaFunc(beam_setFirer) { Beam *b = beam(L); if (b) - b->setFirer(entity(L)); + b->setFirer(entity(L, 2)); luaReturnNil(); } @@ -6171,6 +6180,7 @@ luaFunc(addInfluence) pinf.pos.y = lua_tonumber(L, 2); pinf.size = lua_tonumber(L, 3); pinf.spd = lua_tonumber(L, 4); + pinf.pull = getBool(L, 5); dsq->particleManager->addInfluence(pinf); luaReturnNil(); } @@ -6583,6 +6593,12 @@ luaFunc(entity_pushTarget) luaReturnNil(); } +luaFunc(entity_getPushDamage) +{ + Entity *e = entity(L); + luaReturnNum(e ? e->getPushDamage() : 0.0f); +} + luaFunc(watch) { float t = lua_tonumber(L, 1); @@ -7766,6 +7782,11 @@ luaFunc(getMouseWorldPos) luaReturnVec2(v.x, v.y); } +luaFunc(getMouseWheelChange) +{ + luaReturnNum(core->mouse.scrollWheelChange); +} + luaFunc(fade) { dsq->overlay->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6)); @@ -8696,6 +8717,7 @@ static const struct { luaRegister(setMousePos), luaRegister(getMousePos), luaRegister(getMouseWorldPos), + luaRegister(getMouseWheelChange), luaRegister(resetContinuity), @@ -8756,6 +8778,7 @@ static const struct { luaRegister(entity_getHealth), luaRegister(entity_getMaxHealth), luaRegister(entity_pushTarget), + luaRegister(entity_getPushDamage), luaRegister(entity_msg), luaRegister(node_msg), luaRegister(entity_updateMovement), @@ -9330,6 +9353,7 @@ static const struct { luaRegister(entity_getVel2), luaRegister(entity_clearVel2), + luaRegister(entity_getPushVec), luaRegister(updateMusic), From 84f1b12c67867669b0a80f9735d3ace662315af8 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sun, 29 Sep 2013 01:27:36 +0200 Subject: [PATCH 18/28] Add riding related Lua functions: - entity_getRidingPosition() - entity_getRidingRotation() - entity_getRidingFlip() --- Aquaria/ScriptInterface.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 6b413be..22b627e 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -2435,6 +2435,28 @@ luaFunc(entity_setRidingData) luaReturnNil(); } +luaFunc(entity_getRidingPosition) +{ + Entity *e = entity(L); + Vector v; + if (e) + v = e->getRidingPosition(); + luaReturnVec2(v.x, v.y); +} + +luaFunc(entity_getRidingRotation) +{ + Entity *e = entity(L); + luaReturnNum(e ? e->getRidingRotation() : 0.0f); +} + +luaFunc(entity_getRidingFlip) +{ + Entity *e = entity(L); + luaReturnBool(e && e->getRidingFlip()); +} + + luaFunc(entity_setBoneLock) { Entity *e = entity(L); @@ -8561,6 +8583,9 @@ static const struct { luaRegister(entity_setRidingPosition), luaRegister(entity_setRidingData), + luaRegister(entity_getRidingPosition), + luaRegister(entity_getRidingRotation), + luaRegister(entity_getRidingFlip), luaRegister(entity_setBoneLock), luaRegister(entity_setIngredient), luaRegister(entity_setDeathScene), From d97bb25b9e57f278598d15d384b493d7320185cd Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sat, 19 Oct 2013 17:30:42 +0200 Subject: [PATCH 19/28] Add some Lua functions, changes to hair. + beam_getEndPos() + entity_setCurrentHealth() + entity_setMaxHealth() + beam_getEndPos() + entity_hasAnimation() - Add 3 new parameters to entity_damage: shot, hitX, hitY - entity_getAnimationLength() supports string as 2nd parameter now. This will lookup an animation's length via name. Passing an ANIMLAYER_* constant works as it used to. --- Aquaria/Entity.cpp | 2 +- Aquaria/Hair.cpp | 15 +----------- Aquaria/Hair.h | 8 ++---- Aquaria/ScriptInterface.cpp | 49 ++++++++++++++++++++++++++++++++++--- 4 files changed, 50 insertions(+), 24 deletions(-) diff --git a/Aquaria/Entity.cpp b/Aquaria/Entity.cpp index fbfcb89..e9e180e 100644 --- a/Aquaria/Entity.cpp +++ b/Aquaria/Entity.cpp @@ -3107,7 +3107,7 @@ bool Entity::doCollisionAvoidance(float dt, int search, float mod, Vector *vp, i return false; } -void Entity::initHair(int numSegments, int segmentLength, int width, const std::string &tex) +void Entity::initHair(int numSegments, float segmentLength, float width, const std::string &tex) { if (hair) { diff --git a/Aquaria/Hair.cpp b/Aquaria/Hair.cpp index 80cc0f0..09f5177 100644 --- a/Aquaria/Hair.cpp +++ b/Aquaria/Hair.cpp @@ -25,13 +25,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // nodes = 40 // segmentLength = 3 -Hair::Hair(int nodes, int segmentLength, int hairWidth) : RenderObject() +Hair::Hair(int nodes, float segmentLength, float hairWidth) : RenderObject() { this->segmentLength = segmentLength; this->hairWidth = hairWidth; - waveTimer = 0; - waveAmount = 5; - //hairWidth = 10; cull = false; @@ -46,7 +43,6 @@ Hair::Hair(int nodes, int segmentLength, int hairWidth) : RenderObject() hairNodes[i].percent = 1.0f-perc; hairNodes[i].position = hairNodes[i].originalPosition = hairNodes[i].defaultPosition = Vector(0, i*segmentLength, 0); } - hairTimer = 0; } void Hair::exertWave(float dt) @@ -196,15 +192,6 @@ void Hair::onRender() #endif } -void Hair::updateWaveTimer(float dt) -{ - waveTimer += dt; - for (int i = 1; i < hairNodes.size(); i++) - { - hairNodes[i].defaultPosition = hairNodes[i].originalPosition + Vector(cosf(waveTimer+i)*waveAmount*hairNodes[i].percent, 0, 0); - } -} - void Hair::onUpdate(float dt) { RenderObject::onUpdate(dt); diff --git a/Aquaria/Hair.h b/Aquaria/Hair.h index 14ae3c9..2bb495f 100644 --- a/Aquaria/Hair.h +++ b/Aquaria/Hair.h @@ -38,13 +38,13 @@ struct HairNode class Hair : public RenderObject { public: - Hair(int nodes=40, int segmentLength=3, int width=18); + Hair(int nodes=40, float segmentLength=3, float width=18); void exertForce(const Vector &force, float dt, int usePerc=0); void updatePositions(); void returnToDefaultPositions(float dt); - int hairWidth; + float hairWidth; std::vector hairNodes; @@ -54,10 +54,6 @@ public: void exertGravityWave(float dt); HairNode *getHairNode(int idx); protected: - float hairTimer; - void updateWaveTimer(float dt); - int waveAmount; - float waveTimer; float segmentLength; void onUpdate(float dt); void onRender(); diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 22b627e..2a5fdd9 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -3815,17 +3815,29 @@ luaFunc(entity_getAnimationLength) { Entity *e = entity(L); float ret=0; - int layer = lua_tonumber(L, 2); if (e) { - if (Animation *anim = e->skeletalSprite.getCurrentAnimation(layer)) + Animation *anim = 0; + if (lua_isstring(L, 2)) + anim = e->skeletalSprite.getAnimation(lua_tostring(L, 2)); + else { - ret = anim->getAnimationLength(); + int layer = lua_tointeger(L, 2); + anim = e->skeletalSprite.getCurrentAnimation(layer); } + if (anim) + ret = anim->getAnimationLength(); } luaReturnNum(ret); } +luaFunc(entity_hasAnimation) +{ + Entity *e = entity(L); + Animation *anim = e->skeletalSprite.getAnimation(getString(L, 2)); + luaReturnBool(anim != NULL); +} + luaFunc(entity_isFollowingPath) { Entity *e = entity(L); @@ -4233,6 +4245,15 @@ luaFunc(beam_setPosition_override) luaReturnNil(); } +luaFunc(beam_getEndPos) +{ + Beam *b = beam(L); + Vector v; + if (b) + v = b->endPos; + luaReturnVec2(v.x, v.y); +} + luaFunc(getStringBank) { luaReturnStr(dsq->continuity.stringBank.get(lua_tointeger(L, 1)).c_str()); @@ -4411,6 +4432,8 @@ luaFunc(entity_damage) d.damageType = (DamageType)lua_tointeger(L, 4); d.effectTime = lua_tonumber(L, 5); d.useTimer = !getBool(L, 6); + d.shot = lua_isuserdata(L, 7) ? getShot(L, 7) : NULL; + d.hitPos = Vector(lua_tonumber(L, 8), lua_tonumber(L, 9)); didDamage = e->damage(d); } luaReturnBool(didDamage); @@ -4448,6 +4471,22 @@ luaFunc(entity_setHealth) luaReturnNil(); } +luaFunc(entity_setCurrentHealth) +{ + Entity *e = entity(L, 1); + if (e) + e->health = lua_tonumber(L, 2); + luaReturnNil(); +} + +luaFunc(entity_setMaxHealth) +{ + Entity *e = entity(L, 1); + if (e) + e->maxHealth = lua_tonumber(L, 2); + luaReturnNil(); +} + luaFunc(entity_changeHealth) { Entity *e = entity(L, 1); @@ -8716,6 +8755,7 @@ static const struct { luaRegister(beam_setBeamWidth), luaRegister(beam_setFirer), luaRegister(beam_setDamageType), + luaRegister(beam_getEndPos), luaRegister(getStringBank), @@ -9297,6 +9337,8 @@ static const struct { luaRegister(entity_setHealth), + luaRegister(entity_setCurrentHealth), + luaRegister(entity_setMaxHealth), luaRegister(entity_changeHealth), luaRegister(node_setActive), @@ -9325,6 +9367,7 @@ static const struct { luaRegister(entity_isAnimating), luaRegister(entity_getAnimationName), luaRegister(entity_getAnimationLength), + luaRegister(entity_hasAnimation), luaRegister(entity_setCull), From b0c098bbcdd149cccb55633fa922a3d51cd84a2f Mon Sep 17 00:00:00 2001 From: fgenesis Date: Mon, 21 Oct 2013 02:34:30 +0200 Subject: [PATCH 20/28] Compile fix for prev. commit --- Aquaria/Entity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Aquaria/Entity.h b/Aquaria/Entity.h index 190ad3b..4b4719a 100644 --- a/Aquaria/Entity.h +++ b/Aquaria/Entity.h @@ -486,7 +486,7 @@ public: virtual bool canSetBoneLock(); - void initHair(int numSegments, int segmentLength, int width, const std::string &tex); + void initHair(int numSegments, float segmentLength, float width, const std::string &tex); void updateHair(float dt); void setHairHeadPosition(const Vector &pos); void exertHairForce(const Vector &force, float dt); From fa6ca8d60acfa9a0cb6785f41c74b352ffed082a Mon Sep 17 00:00:00 2001 From: fgenesis Date: Mon, 21 Oct 2013 02:34:57 +0200 Subject: [PATCH 21/28] Add 2 Lua functions: + obj_getWorldScale() + obj_getParent() --- Aquaria/ScriptInterface.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 2a5fdd9..c74edd8 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -1535,6 +1535,21 @@ luaFunc(obj_fadeAlphaWithLife) luaReturnNil(); } +luaFunc(obj_getWorldScale) +{ + RenderObject *r = robj(L); + Vector s; + if (r) + s = r->getRealScale(); + luaReturnVec2(s.x, s.y); +} + +luaFunc(obj_getParent) +{ + RenderObject *r = robj(L); + luaReturnPtr(r ? r->getParent() : NULL); +} + // ----- end RenderObject common functions ----- @@ -1746,6 +1761,8 @@ luaFunc(quad_getBorderAlpha) RO_FUNC(getter, prefix, collideCircleVsLineAngle) \ RO_FUNC(getter, prefix, getVectorToObj ) \ RO_FUNC(getter, prefix, fadeAlphaWithLife ) \ + RO_FUNC(getter, prefix, getWorldScale ) \ + RO_FUNC(getter, prefix, getParent ) \ MK_ALIAS(prefix, fh, flipHorizontal ) \ MK_ALIAS(prefix, fv, flipVertical ) From 69e25640fb42faaf3a937589a6d5fe6ed09aa6a0 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Fri, 25 Oct 2013 01:44:34 +0200 Subject: [PATCH 22/28] Reload shaders on resolution change. --- BBGE/AfterEffect.cpp | 32 +++++++++++++++++++++++++++----- BBGE/AfterEffect.h | 3 ++- BBGE/Shader.cpp | 41 +++++++++++++++++++++++++++-------------- BBGE/Shader.h | 3 ++- 4 files changed, 58 insertions(+), 21 deletions(-) diff --git a/BBGE/AfterEffect.cpp b/BBGE/AfterEffect.cpp index 938d535..6b6b92c 100644 --- a/BBGE/AfterEffect.cpp +++ b/BBGE/AfterEffect.cpp @@ -113,6 +113,13 @@ void AfterEffectManager::deleteShaders() } } +void AfterEffectManager::unloadShaders() +{ + for(size_t i = 0; i < loadedShaders.size(); ++i) + if(loadedShaders[i]) + loadedShaders[i]->unload(); +} + void AfterEffectManager::clear() { deleteEffects(); @@ -196,7 +203,7 @@ void AfterEffectManager::renderGrid() Shader *activeShader = 0; for (size_t i = 0; i < shaderPipeline.size(); ++i) { - if(shaderPipeline[i]) + if(shaderPipeline[i] && shaderPipeline[i]->isLoaded()) { if(firstShader < 0) { @@ -275,7 +282,7 @@ void AfterEffectManager::renderGrid() for(int i = firstShader + 1; i <= lastShader; ++i) { activeShader = shaderPipeline[i]; - if(!activeShader) + if(!(activeShader && activeShader->isLoaded())) continue; // Swap and exchange framebuffers. The old output buffer serves as texture input for the other one @@ -373,7 +380,7 @@ void AfterEffectManager::renderGridPoints() void AfterEffectManager::unloadDevice() { backupBuffer.unloadDevice(); - deleteShaders(); + unloadShaders(); } void AfterEffectManager::reloadDevice() @@ -399,7 +406,22 @@ void AfterEffectManager::reloadDevice() else backupBuffer.init(-1, -1, true); - loadShaders(); + for (size_t i = 0; i < loadedShaders.size(); ++i) + { + if (Shader *sh = loadedShaders[i]) + { + sh->reload(); + if (!sh->isLoaded()) + { + debugLog("AfterEffect::reloadDevice(): Failed to reload shader"); + delete sh; + loadedShaders[i] = 0; + for(size_t j = 0; j < shaderPipeline.size(); ++j) + if(sh == shaderPipeline[j]) + shaderPipeline[j] = 0; + } + } + } } void AfterEffectManager::addEffect(Effect *e) @@ -612,7 +634,7 @@ int AfterEffectManager::_insertShader(Shader *sh) return loadedShaders.size(); } -void AfterEffectManager::unloadShader(int handle) +void AfterEffectManager::deleteShader(int handle) { Shader *sh = getShaderPtr(handle); if(!sh) diff --git a/BBGE/AfterEffect.h b/BBGE/AfterEffect.h index 90c7d9f..251635f 100644 --- a/BBGE/AfterEffect.h +++ b/BBGE/AfterEffect.h @@ -91,6 +91,7 @@ public: void renderGridPoints(); void loadShaders(); + void unloadShaders(); // unloads shaders but keeps code and data intact, so that they can be reloaded. void deleteShaders(); void unloadDevice(); @@ -116,7 +117,7 @@ public: Shader *getShaderPtr(int handle); void setShaderPipelineSize(size_t size); bool setShaderPipelinePos(int handle, size_t pos); - void unloadShader(int handle); + void deleteShader(int handle); protected: int _insertShader(Shader *sh); diff --git a/BBGE/Shader.cpp b/BBGE/Shader.cpp index c6468bc..af5e882 100644 --- a/BBGE/Shader.cpp +++ b/BBGE/Shader.cpp @@ -164,7 +164,10 @@ bool Shader::isLoaded() const void Shader::reload() { - load(vertFile, fragFile); + if (vertFile.size() || fragFile.size()) + load(vertFile, fragFile); + else + loadSrc(vertSrc.c_str(), fragSrc.c_str()); } void Shader::bind() @@ -321,6 +324,9 @@ void Shader::loadSrc(const char *vertCode, const char *fragCode) return; } + vertSrc = vertCode ? vertCode : ""; + fragSrc = fragCode ? fragCode : ""; + _queryUniforms(); #endif @@ -328,15 +334,6 @@ void Shader::loadSrc(const char *vertCode, const char *fragCode) void Shader::_setUniform(Uniform *u) { - /*if(u->location == -1) - { - u->location = glGetUniformLocationARB(g_programObj, u->name); - if(u->location == -1) - { - u->dirty = false; - return; - } - }*/ switch(u->type) { case GL_FLOAT: glUniform1fvARB(u->location, 1, u->data.f); break; @@ -381,9 +378,13 @@ void Shader::_queryUniforms() glGetObjectParameterivARB(g_programObj, GL_OBJECT_ACTIVE_UNIFORMS_ARB , &numUniforms); if (numUniforms <= 0) + { + uniforms.clear(); return; + } uniforms.reserve(numUniforms); + size_t total = 0; for (unsigned int i = 0; i < numUniforms; ++i) { @@ -396,15 +397,27 @@ void Shader::_queryUniforms() u.location = glGetUniformLocationARB(g_programObj, u.name); if(u.location == -1) continue; - u.dirty = false; - u.type = type; - memset(&u.data, 0, sizeof(u.data)); - uniforms.push_back(u); + bool add = total >= uniforms.size(); + if(add || type != u.type) // keep data intact on reload + memset(&u.data, 0, sizeof(u.data)); + u.dirty = true; + u.type = type; + + if(add) + uniforms.push_back(u); + else + uniforms[total] = u; + + ++total; } + uniforms.resize(total); + // sort to be able to do binary search later std::sort(uniforms.begin(), uniforms.end()); + + uniformsDirty = true; } int Shader::_getUniformIndex(const char *name) diff --git a/BBGE/Shader.h b/BBGE/Shader.h index 2b978e7..30b8ba0 100644 --- a/BBGE/Shader.h +++ b/BBGE/Shader.h @@ -44,6 +44,7 @@ public: protected: std::string vertFile, fragFile; + std::string vertSrc, fragSrc; #ifdef BBGE_BUILD_OPENGL GLuint g_programObj; int numUniforms; @@ -72,7 +73,7 @@ private: float f[4]; }; } data; - char name[32]; + char name[64]; bool operator< (const Uniform&) const; }; From 3fe9ffc2cd2981de93b2f6ffd9d230545b65e719 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Fri, 25 Oct 2013 01:47:24 +0200 Subject: [PATCH 23/28] Fix setGemPosition(), add more Lua functions: - isShader() - isParticleEffect() - pe_start() - pe_stop() - pe_isRunning() - isMiniMapCursorOkay() --- Aquaria/Avatar.cpp | 9 ++---- Aquaria/Avatar.h | 2 -- Aquaria/DSQ.cpp | 6 ++++ Aquaria/DSQ.h | 1 + Aquaria/ScriptInterface.cpp | 57 ++++++++++++++++++++++++++++++++++--- BBGE/ParticleEffect.cpp | 1 + BBGE/ScriptObject.cpp | 1 + BBGE/ScriptObject.h | 1 + 8 files changed, 65 insertions(+), 13 deletions(-) diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index a44207b..ddf4b56 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -4470,7 +4470,7 @@ void Avatar::action(int id, int state) if (id == ACTION_PRIMARY && state)// !state { - if (isMiniMapCursorOkay()) + if (dsq->isMiniMapCursorOkay()) { if (this->state.lockedToWall) { @@ -5607,11 +5607,6 @@ Vector Avatar::getHeadPosition() bool lastCursorKeyboard = false; -bool Avatar::isMiniMapCursorOkay() -{ - return ((dsq->inputMode != INPUT_MOUSE) || (!dsq->game->miniMapRender || !dsq->game->miniMapRender->isCursorIn())); -} - void Avatar::onUpdate(float dt) { BBGE_PROF(Avatar_onUpdate); @@ -6427,7 +6422,7 @@ void Avatar::onUpdate(float dt) float len = 0; - if (isMiniMapCursorOkay() && !isActing(ACTION_ROLL) && + if (dsq->isMiniMapCursorOkay() && !isActing(ACTION_ROLL) && _isUnderWater && !riding && !boneLock.on && (movingOn || ((dsq->inputMode == INPUT_JOYSTICK || dsq->inputMode== INPUT_KEYBOARD) || (core->mouse.buttons.left || bursting)))) { diff --git a/Aquaria/Avatar.h b/Aquaria/Avatar.h index 7b3d315..9f51b5c 100644 --- a/Aquaria/Avatar.h +++ b/Aquaria/Avatar.h @@ -158,8 +158,6 @@ public: void onCollide(Entity *e); bool zoomOverriden; void clampPosition(); - - bool isMiniMapCursorOkay(); void splash(bool down); InterpolatedVector myZoom; diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index 2dc65dc..28d8117 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -5099,3 +5099,9 @@ void DSQ::resetLayerPasses() renderObjectLayers[LR_ENTITIES].startPass = -2; renderObjectLayers[LR_ENTITIES].endPass = 5; } + +bool DSQ::isMiniMapCursorOkay() +{ + return ((inputMode != INPUT_MOUSE) || (!game->miniMapRender || !game->miniMapRender->isCursorIn())); +} + diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 60d178a..6a17a0c 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -1572,6 +1572,7 @@ public: virtual void onBackgroundUpdate(); void resetLayerPasses(); + bool isMiniMapCursorOkay(); protected: diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index c74edd8..2f0d1e7 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -371,6 +371,7 @@ static void compile_time_assertions() compile_assert(oo(Path) == oo(Avatar)); compile_assert(oo(Path) == oo(BaseText)); compile_assert(oo(Path) == oo(PauseQuad)); + compile_assert(oo(Path) == oo(ParticleEffect)); #undef oo } #endif @@ -593,6 +594,16 @@ static SkeletalSprite *getSkeletalSprite(Entity *e) return e ? &e->skeletalSprite : NULL; } +static inline +ParticleEffect *getParticle(lua_State *L, int slot = 1) +{ + ParticleEffect *q = (ParticleEffect*)lua_touserdata(L, slot); + ENSURE_TYPE(q, SCO_PARTICLE_EFFECT); + if (!q) + scriptDebug(L, "Invalid Particle Effect"); + return q; +} + static bool looksLikeGlobal(const char *s) { for( ; *s; ++s) @@ -838,6 +849,8 @@ MakeTypeCheckFunc(isWeb, SCO_WEB) MakeTypeCheckFunc(isIng, SCO_INGREDIENT) MakeTypeCheckFunc(isBeam, SCO_BEAM) MakeTypeCheckFunc(isText, SCO_TEXT) +MakeTypeCheckFunc(isShader, SCO_SHADER) +MakeTypeCheckFunc(isParticleEffect, SCO_PARTICLE_EFFECT) #undef MakeTypeCheckFunc @@ -1794,7 +1807,8 @@ luaFunc(quad_getBorderAlpha) MAKE_QUAD_FUNCS(beam, beam ) \ MAKE_ROBJ_FUNCS(getQuad, quad ) \ MAKE_ROBJ_FUNCS(getWeb, web ) \ - MAKE_ROBJ_FUNCS(getText, text ) + MAKE_ROBJ_FUNCS(getText, text ) \ + MAKE_ROBJ_FUNCS(getParticle, pe ) // first time, create them. (There is a second use of this further down, with different MK_* macros) EXPAND_FUNC_PROTOTYPES @@ -7979,8 +7993,9 @@ luaFunc(setGemPosition) if(mapname.empty()) mapname = dsq->game->sceneName; Vector pos(lua_tonumber(L, 2), lua_tonumber(L, 3)); + bool result = false; - WorldMapTile *tile = dsq->continuity.worldMap.getWorldMapTile(getString(L, 1)); + WorldMapTile *tile = dsq->continuity.worldMap.getWorldMapTile(mapname); if(tile) { pos = dsq->game->worldMapRender->getWorldToTile(tile, pos, true, true); @@ -7991,6 +8006,7 @@ luaFunc(setGemPosition) GemData& gem = *it; gem.pos = pos; gem.mapName = mapname; + result = true; } else { @@ -8001,7 +8017,7 @@ luaFunc(setGemPosition) { debugLog("setGemPosition: Map tile does not exist: " + mapname); } - luaReturnNil(); + luaReturnBool(result); } luaFunc(removeGem) @@ -8336,6 +8352,11 @@ luaFunc(getScreenVirtualSize) luaReturnVec2(core->getVirtualWidth(), core->getVirtualHeight()); } +luaFunc(isMiniMapCursorOkay) +{ + luaReturnBool(dsq->isMiniMapCursorOkay()); +} + luaFunc(inv_isFull) { IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); @@ -8557,10 +8578,31 @@ luaFunc(shader_setFloat) luaFunc(shader_delete) { if(core->afterEffectManager) - core->afterEffectManager->unloadShader(lua_tointeger(L, 1)); + core->afterEffectManager->deleteShader(lua_tointeger(L, 1)); luaReturnNil(); } +luaFunc(pe_start) +{ + ParticleEffect *pe = getParticle(L); + if (pe) + pe->start(); + luaReturnNil(); +} + +luaFunc(pe_stop) +{ + ParticleEffect *pe = getParticle(L); + if (pe) + pe->stop(); + luaReturnNil(); +} + +luaFunc(pe_isRunning) +{ + ParticleEffect *pe = getParticle(L); + luaReturnBool(pe && pe->isRunning()); +} //-------------------------------------------------------------------------------------------- @@ -9483,6 +9525,7 @@ static const struct { luaRegister(getScreenVirtualOff), luaRegister(getScreenSize), luaRegister(getScreenVirtualSize), + luaRegister(isMiniMapCursorOkay), luaRegister(inv_isFull), luaRegister(inv_getMaxAmount), @@ -9514,6 +9557,10 @@ static const struct { luaRegister(shader_setInt), luaRegister(shader_delete), + luaRegister(pe_start), + luaRegister(pe_stop), + luaRegister(pe_isRunning), + luaRegister(isQuad), luaRegister(isNode), luaRegister(isObject), @@ -9523,6 +9570,8 @@ static const struct { luaRegister(isIng), luaRegister(isBeam), luaRegister(isText), + luaRegister(isShader), + luaRegister(isParticleEffect), #undef MK_FUNC diff --git a/BBGE/ParticleEffect.cpp b/BBGE/ParticleEffect.cpp index 821fc3b..72dde64 100644 --- a/BBGE/ParticleEffect.cpp +++ b/BBGE/ParticleEffect.cpp @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ParticleEffect::ParticleEffect() : RenderObject() { + addType(SCO_PARTICLE_EFFECT); running = false; waitForParticles = true; effectLife = -1; diff --git a/BBGE/ScriptObject.cpp b/BBGE/ScriptObject.cpp index 60b5d01..b9a8c21 100644 --- a/BBGE/ScriptObject.cpp +++ b/BBGE/ScriptObject.cpp @@ -39,6 +39,7 @@ static const char *scriptObjTypeNames[] = /* (1 <<11) */ "Text", /* (1 <<12) */ "PauseQuad", /* (1 <<13) */ "Shader", + /* (1 <<14) */ "ParticleEffect", NULL }; diff --git a/BBGE/ScriptObject.h b/BBGE/ScriptObject.h index a6bbb0a..710d067 100644 --- a/BBGE/ScriptObject.h +++ b/BBGE/ScriptObject.h @@ -41,6 +41,7 @@ enum ScriptObjectType SCO_TEXT = 0x0800, SCO_PAUSEQUAD = 0x1000, SCO_SHADER = 0x2000, + SCO_PARTICLE_EFFECT = 0x4000, SCO_FORCE_32BIT = 0xFFFFFFFF }; From c312572ff74f1f1ed7f7d8f945c27e7d8f82c7f3 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Mon, 28 Oct 2013 04:27:44 +0100 Subject: [PATCH 24/28] Do not allow rolling when riding. Rolling while riding does not make sense, is not handled/animated at all, and it looks strange. I wonder why nobody has fixed this in all this time. --- Aquaria/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index ddf4b56..1928d7f 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -5222,7 +5222,7 @@ void Avatar::updateWallJump(float dt) void Avatar::updateRoll(float dt) { - if (!inputEnabled || dsq->game->isWorldPaused()) + if (!inputEnabled || dsq->game->isWorldPaused() || riding) { if (rolling) stopRoll(); From 9377b6edb94d37e84f3f346ea6c71b4aba2acaa6 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Mon, 28 Oct 2013 04:28:05 +0100 Subject: [PATCH 25/28] Add Lua function isShuttingDownGameState() --- Aquaria/ScriptInterface.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 2f0d1e7..3c66f70 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -8357,6 +8357,11 @@ luaFunc(isMiniMapCursorOkay) luaReturnBool(dsq->isMiniMapCursorOkay()); } +luaFunc(isShuttingDownGameState) +{ + luaReturnBool(dsq->game->isShuttingDownGameState()); +} + luaFunc(inv_isFull) { IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); @@ -9526,6 +9531,7 @@ static const struct { luaRegister(getScreenSize), luaRegister(getScreenVirtualSize), luaRegister(isMiniMapCursorOkay), + luaRegister(isShuttingDownGameState), luaRegister(inv_isFull), luaRegister(inv_getMaxAmount), From 8d444a3327c80bfce454f5ff3b2e7ac83675942a Mon Sep 17 00:00:00 2001 From: fgenesis Date: Mon, 28 Oct 2013 04:29:46 +0100 Subject: [PATCH 26/28] Get rid of a few unnecessary continueity resets. Continuity resets load a bunch of small files from disk; this speeds up the startup precess very slightly if the files are not in the OS's file cache yet. --- Aquaria/BitBlotLogo.cpp | 2 +- Aquaria/DSQ.cpp | 2 +- Aquaria/Mod.cpp | 4 ---- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Aquaria/BitBlotLogo.cpp b/Aquaria/BitBlotLogo.cpp index 132b49a..6747d0f 100644 --- a/Aquaria/BitBlotLogo.cpp +++ b/Aquaria/BitBlotLogo.cpp @@ -78,7 +78,7 @@ void BitBlotLogo::skipLogo() void BitBlotLogo::getOut() { - dsq->continuity.reset(); + //dsq->continuity.reset(); #ifdef AQUARIA_DEMO dsq->title(); diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index 28d8117..6d53b0a 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -1537,7 +1537,7 @@ This build is not yet final, and as such there are a couple things lacking. They setMousePosition(core->center); - dsq->continuity.reset(); + //dsq->continuity.reset(); loadBit(LOAD_FINISHED); diff --git a/Aquaria/Mod.cpp b/Aquaria/Mod.cpp index d646000..cf21efd 100644 --- a/Aquaria/Mod.cpp +++ b/Aquaria/Mod.cpp @@ -247,17 +247,13 @@ void Mod::applyStart() if (!dsq->runScript(scriptPath, "init")) { debugLog("MOD: runscript failed"); - dsq->continuity.reset(); setActive(false); - dsq->continuity.reset(); dsq->title(); } if (isActive() && dsq->game->sceneToLoad.empty()) { debugLog("MOD: no scene loaded in mod-init"); - dsq->continuity.reset(); setActive(false); - dsq->continuity.reset(); dsq->title(); } else if (isActive()) From 1701c9a67dbf33a37dc04441fb7241fe8d1fa1ec Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sat, 2 Nov 2013 15:22:55 +0100 Subject: [PATCH 27/28] More Lua functions: - entity_hasSkeletal() - entity_getNumAnimLayers() - filterNearestEntities() to fill an internal filter buffer - getNextFilteredEntity() to iterate over the filter buffer --- Aquaria/ScriptInterface.cpp | 78 +++++++++++++++++++++++++++++++++++++ BBGE/SkeletalSprite.h | 1 + 2 files changed, 79 insertions(+) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 3c66f70..acc2e19 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -4065,6 +4065,18 @@ luaFunc(entity_getSkeletalName) luaReturnStr(s); } +luaFunc(entity_hasSkeletal) +{ + Entity *e = entity(L); + luaReturnBool(e && e->skeletalSprite.isLoaded()); +} + +luaFunc(entity_getNumAnimLayers) +{ + Entity *e = entity(L); + luaReturnInt(e ? e->skeletalSprite.getNumAnimLayers() : 0); +} + luaFunc(entity_idle) { Entity *e = entity(L); @@ -7432,6 +7444,68 @@ luaFunc(getNextEntity) luaReturnPtr(dsq->getNextEntity()); } +typedef std::pair EntityDistancePair; +static std::vector filteredEntities(20); +static int filteredIdx = 0; + +static bool _entityDistanceCmp(const EntityDistancePair& a, const EntityDistancePair& b) +{ + return a.second < b.second; +} + +luaFunc(filterNearestEntities) +{ + filteredEntities.clear(); + + const Vector p(lua_tonumber(L, 1), lua_tonumber(L, 2)); + const float radius = lua_tointeger(L, 3); + const Entity *ignore = lua_isuserdata(L, 4) ? entity(L, 4) : NULL; + const EntityType et = lua_isnumber(L, 5) ? (EntityType)lua_tointeger(L, 5) : ET_NOTYPE; + const DamageType dt = lua_isnumber(L, 6) ? (DamageType)lua_tointeger(L, 6) : DT_NONE; + const int lrStart = lua_isnumber(L, 7) ? lua_tointeger(L, 7) : -1; + const int lrEnd = lua_isnumber(L, 8) ? lua_tointeger(L, 8) : -1; + + const float sqrRadius = radius * radius; + float distsq; + const bool skipLayerCheck = lrStart == -1 || lrEnd == -1; + const bool skipRadiusCheck = radius <= 0; + FOR_ENTITIES(i) + { + Entity *e = *i; + distsq = (e->position - p).getSquaredLength2D(); + if (skipRadiusCheck || distsq <= sqrRadius) + { + if (e != ignore && e->isPresent()) + { + if (skipLayerCheck || (e->layer >= lrStart && e->layer <= lrEnd)) + { + if (et == ET_NOTYPE || e->getEntityType() == et) + { + if (dt == DT_NONE || e->isDamageTarget(dt)) + { + filteredEntities.push_back(std::make_pair(e, distsq)); + } + } + } + } + } + } + std::sort(filteredEntities.begin(), filteredEntities.end(), _entityDistanceCmp); + filteredEntities.push_back(std::make_pair((Entity*)NULL, 0.0f)); // terminator + filteredIdx = 0; + luaReturnInt(filteredEntities.size()-1); +} + +luaFunc(getNextFilteredEntity) +{ + EntityDistancePair ep = filteredEntities[filteredIdx]; + if (ep.first) + ++filteredIdx; + luaPushPointer(L, ep.first); + lua_pushnumber(L, ep.second); + return 2; +} + luaFunc(getEntity) { Entity *ent = 0; @@ -8950,6 +9024,8 @@ static const struct { luaRegister(entity_warpSegments), luaRegister(entity_initSkeletal), luaRegister(entity_loadSkin), + luaRegister(entity_hasSkeletal), + luaRegister(entity_getNumAnimLayers), luaRegister(entity_getSkeletalName), luaRegister(entity_initStrands), @@ -9218,6 +9294,8 @@ static const struct { luaRegister(getEntity), luaRegister(getFirstEntity), luaRegister(getNextEntity), + luaRegister(filterNearestEntities), + luaRegister(getNextFilteredEntity), luaRegister(setStory), luaRegister(getStory), diff --git a/BBGE/SkeletalSprite.h b/BBGE/SkeletalSprite.h index 6841106..570c4bf 100644 --- a/BBGE/SkeletalSprite.h +++ b/BBGE/SkeletalSprite.h @@ -251,6 +251,7 @@ public: void selectNextBone(); bool isLoaded(); + int getNumAnimLayers() const { return animLayers.size(); } AnimationLayer* getAnimationLayer(int l); int getBoneIdx(Bone *b); From e8b9261004d7e644eedbee4df03b6c97bb268814 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Tue, 5 Nov 2013 14:53:57 +0100 Subject: [PATCH 28/28] Attempt to fix some VFS problems --- ExternalLibs/ttvfs/VFSDir.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ExternalLibs/ttvfs/VFSDir.cpp b/ExternalLibs/ttvfs/VFSDir.cpp index 536ab72..6d0d6d8 100644 --- a/ExternalLibs/ttvfs/VFSDir.cpp +++ b/ExternalLibs/ttvfs/VFSDir.cpp @@ -97,6 +97,10 @@ bool VFSDir::merge(VFSDir *dir, bool overwrite, EntryFlags flag) if(dir == this) return true; // nothing to do then + // HACK: make sure the files are there before merging + this->load(false); + dir->load(false); + bool result = false; VFS_GUARD_OPT(this);