1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-02-13 16:16:08 +00:00

Merge branch 'experimental' of file:///Users/User/code/coding/Aquaria_fg_clean into experimental

This commit is contained in:
fgenesis 2014-05-21 00:04:43 +01:00
commit d2fdbddd5a
13 changed files with 226 additions and 139 deletions

View file

@ -3561,7 +3561,7 @@ void Avatar::lockToWall()
while(0);
}
if (dsq->game->getGrid(t)==OT_HURT && isDamageTarget(DT_WALLHURT))
if (dsq->game->isObstructed(t, OT_HURT) && isDamageTarget(DT_WALLHURT))
{
good = false;
}
@ -3612,16 +3612,16 @@ void Avatar::lockToWall()
Vector offdiff = t.worldVector() - position;
if (!offdiff.isZero())
{
if (tileType != OT_INVISIBLEIN)
if (tileType & OT_INVISIBLEIN)
{
Vector adjust = offdiff;
adjust.setLength2D(TILE_SIZE*2);
adjust.setLength2D(TILE_SIZE/2);
offdiff -= adjust;
}
else
{
Vector adjust = offdiff;
adjust.setLength2D(TILE_SIZE/2);
adjust.setLength2D(TILE_SIZE*2);
offdiff -= adjust;
}
}

View file

@ -813,7 +813,10 @@ void loadBitForTexPrecache()
void DSQ::setVersionLabelText()
{
#ifdef AQUARIA_OVERRIDE_VERSION_STRING
versionLabel->setText(AQUARIA_OVERRIDE_VERSION_STRING);
std::string overrideText = AQUARIA_OVERRIDE_VERSION_STRING;
if(user.system.allowDangerousScriptFunctions)
overrideText += continuity.stringBank.get(2050);
versionLabel->setText(overrideText);
return;
#endif
@ -848,6 +851,9 @@ void DSQ::setVersionLabelText()
os << AQUARIA_CUSTOM_BUILD_ID;
#endif
if(user.system.allowDangerousScriptFunctions)
os << continuity.stringBank.get(2050);
versionLabel->setText(os.str());
}
@ -907,13 +913,13 @@ This build is not yet final, and as such there are a couple things lacking. They
// steam gets inited in here
Core::init();
dsq->continuity.stringBank.load();
continuity.stringBank.load();
vars = &v;
v.load();
// steam callbacks are inited here
dsq->continuity.init();
continuity.init();
// do copy stuff
#ifdef BBGE_BUILD_UNIX

View file

@ -1509,13 +1509,13 @@ bool Entity::isSittingOnInvisibleIn()
{
for (int y = 0; y < 4; y++)
{
if (dsq->game->getGrid(TileVector(t.x+x, t.y+y))==OT_INVISIBLEIN)
if (dsq->game->isObstructed(TileVector(t.x+x, t.y+y), OT_INVISIBLEIN))
return true;
if (dsq->game->getGrid(TileVector(t.x-x, t.y+y))==OT_INVISIBLEIN)
if (dsq->game->isObstructed(TileVector(t.x-x, t.y+y), OT_INVISIBLEIN))
return true;
if (dsq->game->getGrid(TileVector(t.x+x, t.y-y))==OT_INVISIBLEIN)
if (dsq->game->isObstructed(TileVector(t.x+x, t.y-y), OT_INVISIBLEIN))
return true;
if (dsq->game->getGrid(TileVector(t.x-x, t.y-y))==OT_INVISIBLEIN)
if (dsq->game->isObstructed(TileVector(t.x-x, t.y-y), OT_INVISIBLEIN))
return true;
}
}
@ -3055,6 +3055,7 @@ bool Entity::doCollisionAvoidance(float dt, int search, float mod, Vector *vp, i
int minDist=-1;
TileVector t(position);
TileVector useTile;
const int blockObs = ~ignoreObs;
float totalDist = sqrtf(float(sqr((search*2)*TILE_SIZE)+sqr((search*2)*TILE_SIZE)));
for (int x = -search; x <= search; x++)
@ -3069,7 +3070,7 @@ bool Entity::doCollisionAvoidance(float dt, int search, float mod, Vector *vp, i
}
if (waterBlocked || dsq->game->isObstructed(checkT))
{
if (dsq->game->getGrid(checkT) != ignoreObs)
if (dsq->game->isObstructed(checkT, blockObs))
{
Vector vtc(t.x+x, t.y+y);
Vector vt(t.x, t.y);

View file

@ -2075,8 +2075,8 @@ void Game::fillGridFromQuad(Quad *q, ObsType obsType, bool trim)
//dsq->game->setGrid(TileVector(tpos.x+(w2*TILE_SIZE)+(x/TILE_SIZE), tpos.y+(h2*TILE_SIZE)+(y/TILE_SIZE)), obsType);
TileVector tvec(tpos.x+w2+x, tpos.y+h2+y);
if (dsq->game->getGrid(tvec) == OT_EMPTY)
dsq->game->setGrid(tvec, obsType);
if (!dsq->game->isObstructed(tvec))
dsq->game->addGrid(tvec, obsType);
}
glPopMatrix();
@ -2103,7 +2103,7 @@ void Game::clearDynamicGrid(unsigned char maskbyte /* = OT_MASK_BLACK */)
// otherwise there is a chance to write a few bytes over the end of the buffer -- FG
compile_assert(sizeof(grid) % sizeof(uint32) == 0);
signed char *gridstart = &grid[0][0];
unsigned char *gridstart = &grid[0][0];
uint32 *gridend = (uint32*)(gridstart + sizeof(grid));
uint32 *gridptr = (uint32*)gridstart;
// mask out specific bytes
@ -2165,9 +2165,9 @@ void Game::trimGrid()
// from beeing drawn. (The maps were designed with this mind...)
for (int x = 0; x < MAX_GRID; x++)
{
const signed char *curCol = dsq->game->getGridColumn(x);
const signed char *leftCol = dsq->game->getGridColumn(x-1);
const signed char *rightCol = dsq->game->getGridColumn(x+1);
const unsigned char *curCol = grid[x]; // safe
const unsigned char *leftCol = dsq->game->getGridColumn(x-1); // unsafe
const unsigned char *rightCol = dsq->game->getGridColumn(x+1); // unsafe
for (int y = 0; y < MAX_GRID; y++)
{
if (curCol[y] & OT_MASK_BLACK)
@ -2179,6 +2179,66 @@ void Game::trimGrid()
}
}
void Game::dilateGrid(unsigned int radius, ObsType test, ObsType set, ObsType allowOverwrite)
{
if(!radius)
return;
const int lim = MAX_GRID - radius;
const unsigned int denyOverwrite = ~allowOverwrite;
// Box dilation is separable, so we do a two-pass by axis
int dilate = 0;
// dilate rows
for (int y = 0; y < MAX_GRID; ++y)
{
for (int x = radius; x < lim; ++x)
{
if (grid[x][y] & test)
{
dilate = 2 * radius;
goto doDilate1;
}
if(dilate)
{
--dilate;
doDilate1:
if((grid[x - radius][y] & denyOverwrite) == OT_EMPTY)
grid[x - radius][y] |= set;
}
}
assert(lim + dilate < MAX_GRID);
for(int x = 0; x < dilate; ++x)
if(!(grid[x][y - radius] & test))
grid[x][y - radius] |= set;
}
// dilate colums
dilate = 0;
for (int x = 0; x < MAX_GRID; ++x)
{
unsigned char * const curCol = grid[x];
for (int y = radius; y < lim; ++y)
{
if (curCol[y] & test)
{
dilate = 2 * radius;
goto doDilate2;
}
if(dilate)
{
--dilate;
doDilate2:
if((curCol[y - radius] & denyOverwrite) == OT_EMPTY)
curCol[y - radius] |= set;
}
}
assert(lim + dilate < MAX_GRID);
for(int y = 0; y < dilate; ++y)
if(!(curCol[y - radius] & test))
curCol[y - radius] |= set;
}
}
float Game::getCoverage(Vector pos, int sampleArea)
{
TileVector t(pos);
@ -6451,30 +6511,46 @@ void Game::applyState()
addRenderObject(songLineRender, LR_HUD);
gridRender = new GridRender(OT_INVISIBLE);
gridRender->color = Vector(1, 0, 0);
addRenderObject(gridRender, LR_DEBUG_TEXT);
gridRender->alpha = 0;
gridRender2 = new GridRender(OT_HURT);
gridRender2->color = Vector(1, 1, 0);
addRenderObject(gridRender2, LR_DEBUG_TEXT);
gridRender2->alpha = 0;
gridRender3 = new GridRender(OT_INVISIBLEIN);
gridRender3->color = Vector(1, 0.5f, 0);
addRenderObject(gridRender3, LR_DEBUG_TEXT);
gridRender3->alpha = 0;
edgeRender = new GridRender(OT_BLACKINVIS);
edgeRender->color = Vector(0.3f, 0, 0.6f);
addRenderObject(edgeRender, LR_DEBUG_TEXT);
edgeRender->alpha = 0;
gridRenderEnt = new GridRender(OT_INVISIBLEENT);
gridRenderEnt->color = Vector(0, 1, 0.5);
addRenderObject(gridRenderEnt, LR_DEBUG_TEXT);
gridRenderEnt->alpha = 0;
gridRenderUser1 = new GridRender(OT_USER1);
addRenderObject(gridRenderUser1, LR_DEBUG_TEXT);
gridRenderUser1->color = Vector(1, 0, 1);
gridRenderUser1->alpha = 0;
gridRenderUser2 = new GridRender(OT_USER2);
addRenderObject(gridRenderUser2, LR_DEBUG_TEXT);
gridRenderUser2->color = Vector(1, 1, 1);
gridRenderUser2->alpha = 0;
waterSurfaceRender = new WaterSurfaceRender();
//waterSurfaceRender->setRenderPass(-1);
addRenderObject(waterSurfaceRender, LR_WATERSURFACE);
GridRender *blackRender = new GridRender(OT_BLACK);
blackRender->color = Vector(0, 0, 0);
//blackRender->alpha = 0;
blackRender->blendEnabled = false;
addRenderObject(blackRender, LR_ELEMENTS4);
@ -8515,22 +8591,17 @@ void Game::toggleMiniMapRender(int v)
void Game::toggleGridRender()
{
float t = 0;
float a = 0;
if (gridRender->alpha == 0)
{
gridRender->alpha.interpolateTo(0.5, t);
gridRender2->alpha.interpolateTo(0.5, t);
gridRender3->alpha.interpolateTo(0.5, t);
edgeRender->alpha.interpolateTo(0.5, t);
gridRenderEnt->alpha.interpolateTo(0.5, t);
}
else if (gridRender->alpha == 0.5)
{
gridRender->alpha.interpolateTo(0, t);
gridRender2->alpha.interpolateTo(0, t);
gridRender3->alpha.interpolateTo(0, t);
edgeRender->alpha.interpolateTo(0, t);
gridRenderEnt->alpha.interpolateTo(0, t);
}
a = 0.5f;
gridRender->alpha.interpolateTo(a, t);
gridRender2->alpha.interpolateTo(a, t);
gridRender3->alpha.interpolateTo(a, t);
edgeRender->alpha.interpolateTo(a, t);
gridRenderEnt->alpha.interpolateTo(a, t);
gridRenderUser1->alpha.interpolateTo(a, t);
gridRenderUser2->alpha.interpolateTo(a, t);
}
Vector Game::getCameraPositionFor(const Vector &pos)
@ -10624,7 +10695,7 @@ void Game::setGrid(ElementTemplate *et, Vector position, float rot360)
}
TileVector s(t.x+x, t.y+y);
//Vector v = Vector(position.x+et->grid[i].x*TILE_SIZE, position.y+et->grid[i].y*TILE_SIZE);
setGrid(s, 1);
setGrid(s, OT_INVISIBLE);
}
}
@ -10752,6 +10823,12 @@ void Game::removeState()
miniMapRender = 0;
gridRender = 0;
gridRender2 = 0;
gridRender3 = 0;
edgeRender = 0;
gridRenderEnt = 0;
gridRenderUser1 = 0;
gridRenderUser2 = 0;
worldMapRender = 0;
//core->sound->stopStreamingOgg();
@ -10922,44 +10999,6 @@ bool Game::collideCircleWithGrid(const Vector& position, float r)
return false;
}
bool Game::collideBoxWithGrid(const Vector& position, int hw, int hh)
{
Vector tile = position;
TileVector t(tile);
tile.x = t.x;
tile.y = t.y;
float hsz = TILE_SIZE/2;
int xrange=1,yrange=1;
xrange = (hw/TILE_SIZE)+1;
yrange = (hh/TILE_SIZE)+1;
for (int x = tile.x-xrange; x <= tile.x+xrange; x++)
{
for (int y = tile.y-yrange; y <= tile.y+yrange; y++)
{
int v = this->getGrid(TileVector(x, y));
if (v == 1)
{
if (tile.x == x && tile.y == y) return true;
float rx = (x*TILE_SIZE)+TILE_SIZE/2;
float ry = (y*TILE_SIZE)+TILE_SIZE/2;
if (isBoxIn(position, Vector(hw, hh), Vector(rx, ry), Vector(hsz, hsz)))
{
return true;
}
if (isBoxIn(Vector(rx, ry), Vector(hsz, hsz), position, Vector(hw, hh)))
{
return true;
}
}
}
}
return false;
}
void Game::learnedRecipe(Recipe *r, bool effects)
{
if (nocasecmp(dsq->getTopStateData()->name,"Game")==0 && !applyingState)

View file

@ -587,6 +587,14 @@ enum ObsType
// set by entities
OT_INVISIBLEENT = 0x20,
// mask for all bits that block
OT_BLOCKING = OT_MASK_BLACK | OT_INVISIBLE | OT_INVISIBLEIN | OT_HURT | OT_INVISIBLEENT,
// free for use, not colliding by default
OT_USER1 = 0x40,
OT_USER2 = 0x80,
OT_USER_MASK = OT_USER1 | OT_USER2,
};
struct EntitySaveData
@ -620,12 +628,14 @@ public:
std::string getSelectedChoice() { return selectedChoice; }
int getGrid(const TileVector &tile) const;
int getGridRaw(unsigned int x, unsigned int y) const;
const signed char *getGridColumn(int tileX);
void setGrid(const TileVector &tile, int v);
bool isObstructed(const TileVector &tile, int t = -1) const;
ObsType getGrid(const TileVector &tile) const;
ObsType getGridRaw(const TileVector &tile) const;
unsigned char *getGridColumn(int tileX);
void setGrid(const TileVector &tile, ObsType v);
void addGrid(const TileVector &tile, ObsType v);
bool isObstructed(const TileVector &tile, int t = OT_BLOCKING) const;
void trimGrid();
void dilateGrid(unsigned int radius, ObsType test, ObsType set, ObsType allowOverwrite);
void clearPointers();
@ -655,7 +665,6 @@ public:
void registerSporeDrop(const Vector &pos, int t);
bool collideBoxWithGrid(const Vector& position, int w, int h);
bool collideCircleWithGrid(const Vector& position, float r);
bool collideHairVsCircle(Entity *a, int num, const Vector &pos2, float radius, float perc=0, int *colSegment=0);
@ -959,7 +968,7 @@ public:
void createGradient();
std::string saveMusic;
GridRender *gridRender, *gridRender2, *gridRender3, *edgeRender, *gridRenderEnt;
GridRender *gridRender, *gridRender2, *gridRender3, *edgeRender, *gridRenderEnt, *gridRenderUser1, *gridRenderUser2;
void toggleGridRender();
ElementUpdateList elementUpdateList;
ElementUpdateList elementInteractionList;
@ -1174,7 +1183,7 @@ protected:
void toggleSceneEditor();
#endif
signed char grid[MAX_GRID][MAX_GRID];
unsigned char grid[MAX_GRID][MAX_GRID];
Quad *bg, *bg2;
@ -1200,21 +1209,23 @@ extern Game *game;
// INLINE FUNCTIONS
inline
int Game::getGridRaw(unsigned int x, unsigned int y) const
ObsType Game::getGridRaw(const TileVector &tile) const
{
return grid[x][y];
return (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
? ObsType(grid[tile.x][tile.y])
: OT_INVISIBLE;
}
inline
int Game::getGrid(const TileVector &tile) const
ObsType Game::getGrid(const TileVector &tile) const
{
//if (tile.x < 0 || tile.x >= MAX_GRID || tile.y < 0 || tile.y >= MAX_GRID) return OT_INVISIBLE;
//return grid[tile.x][tile.y];
return (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID)) ? grid[tile.x][tile.y] : OT_INVISIBLE;
return (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
? ObsType(grid[tile.x][tile.y] & OT_BLOCKING)
: OT_INVISIBLE;
}
inline
const signed char *Game::getGridColumn(int tileX)
unsigned char *Game::getGridColumn(int tileX)
{
if (tileX < 0)
return grid[0];
@ -1225,14 +1236,21 @@ const signed char *Game::getGridColumn(int tileX)
}
inline
void Game::setGrid(const TileVector &tile, int v)
void Game::setGrid(const TileVector &tile, ObsType v)
{
if (tile.x < 0 || tile.x >= MAX_GRID || tile.y < 0 || tile.y >= MAX_GRID) return;
grid[tile.x][tile.y] = v;
if (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
grid[tile.x][tile.y] = v;
}
inline
bool Game::isObstructed(const TileVector &tile, int t /* = -1 */) const
void Game::addGrid(const TileVector &tile, ObsType v)
{
if (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
grid[tile.x][tile.y] |= v;
}
inline
bool Game::isObstructed(const TileVector &tile, int t /* = OT_BLOCKING */) const
{
return (getGrid(tile) & t);
}

View file

@ -66,30 +66,6 @@ inline static void doRenderGrid(int x, int startCol, int endCol)
void GridRender::onRender()
{
switch(obsType)
{
case OT_INVISIBLE:
core->setColor(1, 0, 0, alpha.getValue());
break;
case OT_INVISIBLEIN:
core->setColor(1, 0.5, 0, alpha.getValue());
break;
case OT_INVISIBLEENT:
core->setColor(0, 1, 0.5, alpha.getValue());
break;
case OT_BLACK:
core->setColor(0, 0, 0, 1);
break;
case OT_BLACKINVIS:
core->setColor(0.3, 0, 0.6, alpha.getValue());
break;
case OT_HURT:
core->setColor(1, 1, 0, alpha.getValue());
break;
default:
break;
}
const signed char obsType = this->obsType;
Vector camPos = core->cameraPos;
camPos.x -= core->getVirtualOffX() * (core->invGlobalScale);
@ -112,11 +88,11 @@ void GridRender::onRender()
return;
for (int x = startX; x <= endX; ++x)
{
const signed char *gridColumn = dsq->game->getGridColumn(x);
const unsigned char *gridColumn = dsq->game->getGridColumn(x);
int startCol = -1, y;
// fast-forward to next drawable byte
if(const signed char *next = (const signed char*)memchr(gridColumn + startY, obsType, endY - startY + 1)) // find next byte with correct obs type
if(const unsigned char *next = (const unsigned char*)memchr(gridColumn + startY, obsType, endY - startY + 1)) // find next byte with correct obs type
{
y = next - gridColumn; // will get incremented right away, which is okay, because we alrady set startCol
startCol = y;
@ -131,7 +107,7 @@ void GridRender::onRender()
doRenderGrid(x, startCol, y - 1);
// fast-forward to next drawable byte
if(const signed char *next = (const signed char*)memchr(gridColumn + y, obsType, endY - y)) // find next byte with correct obs type
if(const unsigned char *next = (const unsigned char*)memchr(gridColumn + y, obsType, endY - y)) // find next byte with correct obs type
{
y = next - gridColumn; // will get incremented right away, which is okay, because we alrady set startCol
startCol = y;

View file

@ -24,16 +24,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "DSQ.h"
#include "Game.h"
class SearchGrid
class SearchGridRaw
{
public:
SearchGrid() : game(dsq->game) {}
SearchGridRaw(ObsType blocking) : game(dsq->game), blockingObsBits(blocking) {}
inline bool operator()(unsigned x, unsigned y) const
{
return game->getGrid(TileVector(x, y)) == OT_EMPTY;
return (game->getGridRaw(TileVector(x, y)) & blockingObsBits) == OT_EMPTY;
}
private:
const ObsType blockingObsBits;
const Game *game;
};
@ -157,7 +158,7 @@ void PathFinding::generatePath(RenderObject *ro, TileVector start, TileVector go
VectorPath& vp = ro->position.data->path;
vp.clear();
SearchGrid grid;
SearchGridRaw grid(OT_BLOCKING);
JPS::PathVector path;
if(JPS::findPath(path, grid, start.x, start.y, goal.x, goal.y, 1))
{
@ -166,9 +167,12 @@ void PathFinding::generatePath(RenderObject *ro, TileVector start, TileVector go
}
}
bool PathFinding::generatePathSimple(VectorPath& path, const Vector& start, const Vector& end, unsigned int step /* = 0 */)
bool PathFinding::generatePathSimple(VectorPath& path, const Vector& start, const Vector& end, unsigned int step /* = 0 */, unsigned int obs /* = 0 */)
{
SearchGrid grid;
if(obs == OT_EMPTY)
obs = OT_BLOCKING;
SearchGridRaw grid((ObsType)obs);
JPS::PathVector p;
TileVector tstart(start);
TileVector tend(end);

View file

@ -37,7 +37,7 @@ public:
void molestPath(VectorPath &path);
void generatePath(RenderObject *go, TileVector g1, TileVector g2, int offx=0, int offy=0);
bool generatePathSimple(VectorPath& path, const Vector& start, const Vector& end, unsigned int step = 0);
bool generatePathSimple(VectorPath& path, const Vector& start, const Vector& end, unsigned int step = 0, unsigned int obs = 0);
};
#endif

View file

@ -60,6 +60,9 @@ bool complainOnGlobalVar = false;
// thread-local variable.
bool complainOnUndefLocal = false;
// Set to true to make 'os' and 'io' Lua tables accessible
bool allowUnsafeFunctions = false;
// List of all interface functions called by C++ code, terminated by NULL.
static const char * const interfaceFunctions[] = {
@ -2898,6 +2901,16 @@ luaFunc(reconstructEntityGrid)
luaReturnNil();
}
luaFunc(dilateGrid)
{
unsigned int radius = lua_tointeger(L, 1);
ObsType test = (ObsType)lua_tointeger(L, 2);
ObsType set = (ObsType)lua_tointeger(L, 3);
ObsType allowOverwrite = (ObsType)lua_tointeger(L, 4);
dsq->game->dilateGrid(radius, test, set, allowOverwrite);
luaReturnNil();
}
luaFunc(entity_setCanLeaveWater)
{
Entity *e = entity(L);
@ -8347,6 +8360,11 @@ luaFunc(getObstruction)
luaReturnInt(dsq->game->getGrid(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)))));
}
luaFunc(getGridRaw)
{
luaReturnInt(dsq->game->getGridRaw(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)))));
}
luaFunc(isObstructedBlock)
{
float x = lua_tonumber(L, 1);
@ -8568,13 +8586,14 @@ luaFunc(isShuttingDownGameState)
luaReturnBool(dsq->game->isShuttingDownGameState());
}
// startx, starty, endx, endy [, step, xtab, ytab]
// startx, starty, endx, endy [, step, xtab, ytab, obsMask]
luaFunc(findPath)
{
VectorPath path;
Vector start(lua_tonumber(L, 1), lua_tonumber(L, 2));
Vector end(lua_tonumber(L, 3), lua_tonumber(L, 4));
if(!dsq->pathFinding.generatePathSimple(path, start, end, lua_tointeger(L, 5)))
ObsType obs = ObsType(lua_tointeger(L, 8));
if(!dsq->pathFinding.generatePathSimple(path, start, end, lua_tointeger(L, 5), obs))
luaReturnBool(false);
const unsigned num = path.getNumPathNodes();
@ -8964,6 +8983,7 @@ static const struct {
luaRegister(reconstructGrid),
luaRegister(reconstructEntityGrid),
luaRegister(dilateGrid),
luaRegister(ing_hasIET),
luaRegister(ing_getIngredientName),
@ -9463,6 +9483,7 @@ static const struct {
luaRegister(isObstructed),
luaRegister(isObstructedBlock),
luaRegister(getObstruction),
luaRegister(getGridRaw),
luaRegister(findPath),
luaRegister(castLine),
luaRegister(getUserInputString),
@ -10597,6 +10618,11 @@ static const struct {
luaConstant(OT_INVISIBLEIN),
luaConstant(OT_HURT),
luaConstant(OT_INVISIBLEENT),
luaConstant(OT_USER1),
luaConstant(OT_USER2),
luaConstant(OT_MASK_BLACK),
luaConstant(OT_BLOCKING),
luaConstant(OT_USER_MASK),
luaConstant(SEE_MAP_NEVER),
luaConstant(SEE_MAP_DEFAULT),
@ -10627,6 +10653,8 @@ void ScriptInterface::init()
complainOnGlobalVar = devmode;
complainOnUndefLocal = devmode;
allowUnsafeFunctions = dsq->user.system.allowDangerousScriptFunctions;
if (!baseState)
baseState = createLuaVM();
}
@ -10646,11 +10674,15 @@ void *ScriptInterface::the_alloc(void *ud, void *ptr, size_t osize, size_t nsize
lua_State *ScriptInterface::createLuaVM()
{
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. */
luaopen_math(state); /* opens the math lib. */
luaopen_debug(state);
luaL_openlibs(state);
if(!allowUnsafeFunctions)
{
lua_pushnil(state);
lua_setglobal(state, "os");
lua_pushnil(state);
lua_setglobal(state, "io");
}
// Set up various tables for state management:

View file

@ -60,6 +60,12 @@ void UserSettings::save()
xml_devmode.SetAttribute("on", system.devModeOn);
}
xml_system.InsertEndChild(xml_devmode);
TiXmlElement xml_unsafe("AllowDangerousScriptFunctions");
{
xml_unsafe.SetAttribute("on", system.allowDangerousScriptFunctions);
}
xml_system.InsertEndChild(xml_unsafe);
}
doc.InsertEndChild(xml_system);
@ -382,6 +388,12 @@ void UserSettings::load(bool doApply, const std::string &overrideFile)
{
xml_devmode->Attribute("on", &system.devModeOn);
}
TiXmlElement *xml_unsafe = xml_system->FirstChildElement("AllowDangerousScriptFunctions");
if (xml_unsafe)
{
xml_unsafe->Attribute("on", &system.allowDangerousScriptFunctions);
}
}
TiXmlElement *xml_audio = doc.FirstChildElement("Audio");

View file

@ -78,10 +78,11 @@ class UserSettings
public:
struct System
{
System() { debugLogOn = 0; devModeOn = 0; }
System() { debugLogOn = 0; devModeOn = 0; allowDangerousScriptFunctions = 0; }
int debugLogOn;
std::string locale;
int devModeOn;
int allowDangerousScriptFunctions;
} system;
struct Audio

View file

@ -1694,18 +1694,15 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
Animation *SkeletalSprite::getCurrentAnimation(int layer)
{
return animLayers[layer].getCurrentAnimation();
return layer < animLayers.size() ? animLayers[layer].getCurrentAnimation() : NULL;
}
void SkeletalSprite::setTime(float time, int layer)
{
animLayers[layer].timer = time;
if(layer < animLayers.size())
animLayers[layer].timer = time;
}
// hack:
// calculate based on frames
const int lerpAvg = 3;
void AnimationLayer::updateBones()
{
if (!animating && !(&s->animLayers[0] == this) && fallThru == 0) return;

View file

@ -208,6 +208,7 @@
2032 [Achievements]
2033 Retrieving online mod list...
2034 Open URL in web browser?
2050 -- WARNING: Dangerous script functions are ENABLED!
2100 === for options menu ===
2101 Action
2102 Key 1