mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-02-11 22:54:00 +00:00
Script interface: - entity_msg() will no longer corrupt the Lua stack if sending messages to itself. - added more info to non-critical Lua errors ("attempt to call a nil value", etc) - replaced many lua_tostring() with getString(), which does never return NULL. This prevents possible crashes when a non-string parameter is passed to functions expecting a string. Misc: - Removed classes BoxElement, DFSprite, Datafile, and related references. They were essentially unused. - Removed unused Element class member variables. - Show more lines in the in-game console.
434 lines
8.5 KiB
C++
434 lines
8.5 KiB
C++
/*
|
|
Copyright (C) 2007, 2010 - Bit-Blot
|
|
|
|
This file is part of Aquaria.
|
|
|
|
Aquaria is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
#include "Element.h"
|
|
#include "Game.h"
|
|
#include "Avatar.h"
|
|
|
|
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;
|
|
|
|
setStatic(true);
|
|
}
|
|
|
|
void Element::wavyPull(int to, int from, float dt)
|
|
{
|
|
Vector diff = wavy[to] - wavy[from];
|
|
if (!diff.isZero())
|
|
{
|
|
diff.capLength2D(wavyMax);
|
|
if (diff.isLength2DIn(wavyMin))
|
|
{
|
|
diff.setLength2D(wavyMin);
|
|
}
|
|
wavy[to] = wavy[from] + diff;
|
|
}
|
|
}
|
|
|
|
void Element::updateEffects(float dt)
|
|
{
|
|
switch (elementEffectType)
|
|
{
|
|
case EFX_ALPHA:
|
|
alpha.update(dt);
|
|
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))
|
|
{
|
|
int touchIdx = -1;
|
|
Vector pos = position;
|
|
pos.y = position.y - (height*scale.y)/2;
|
|
|
|
float hitPerc=0;
|
|
Vector p = dsq->game->avatar->position;// + Vector(200,0);
|
|
if (p.x > position.x-16 && p.x < position.x+16)
|
|
{
|
|
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;
|
|
if (ramp < 0) ramp = 0;
|
|
if (ramp > 1) ramp = 1;
|
|
|
|
wavyMagnitude = 100 * ramp + 16;
|
|
|
|
if (dsq->game->avatar->vel.x < 0)
|
|
wavyMagnitude = -wavyMagnitude;
|
|
|
|
/*
|
|
if (hitPerc > 0.35f)
|
|
wavyMagnitude = -wavyMagnitude;
|
|
*/
|
|
|
|
wavyAngleOffset = (hitPerc-0.5f)*PI;
|
|
|
|
wavySave = wavy;
|
|
wavyLerpIn = 0;
|
|
}
|
|
|
|
if (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 weight = float(i)/float(wavy.size());
|
|
if (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())
|
|
{
|
|
if (wavyLerpIn < 1)
|
|
wavy[i].x = wavy[i].x*wavyLerpIn + (wavySave[i].x*(1.0f-wavyLerpIn));
|
|
}
|
|
}
|
|
|
|
if (wavyLerpIn < 1)
|
|
{
|
|
wavyLerpIn += dt*lerpSpd;
|
|
if (wavyLerpIn > 1)
|
|
wavyLerpIn = 1;
|
|
}
|
|
wavyAngleOffset += dt*spd;
|
|
if (wavyMagnitude > 0)
|
|
{
|
|
wavyMagnitude -= magRedSpd*dt;
|
|
if (wavyMagnitude < 0)
|
|
wavyMagnitude = 0;
|
|
}
|
|
else
|
|
{
|
|
wavyMagnitude += magRedSpd*dt;
|
|
if (wavyMagnitude > 0)
|
|
wavyMagnitude = 0;
|
|
}
|
|
|
|
//std::cout << "setting grid from wav w/ wavyWaving\n";
|
|
setGridFromWavy();
|
|
|
|
}
|
|
else
|
|
{
|
|
//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;
|
|
}
|
|
}
|
|
|
|
void Element::update(float dt)
|
|
{
|
|
BBGE_PROF(Element_update);
|
|
if (!core->particlesPaused)
|
|
{
|
|
updateLife(dt);
|
|
updateEffects(dt);
|
|
if (drawGrid)
|
|
updateGrid(dt);
|
|
}
|
|
|
|
// updateCullVariables();
|
|
}
|
|
|
|
Element::~Element()
|
|
{
|
|
}
|
|
|
|
void Element::destroy()
|
|
{
|
|
Quad::destroy();
|
|
}
|
|
|
|
int Element::getElementEffectIndex()
|
|
{
|
|
return elementEffectIndex;
|
|
}
|
|
|
|
void Element::setGridFromWavy()
|
|
{
|
|
if (drawGrid)
|
|
{
|
|
//std::cout << "set grid from wavy (" << xDivs << ", " << yDivs << ")\n"
|
|
|
|
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())
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//std::cout << "no drawgrid...\n";
|
|
}
|
|
}
|
|
|
|
void Element::setElementEffectByIndex(int eidx)
|
|
{
|
|
deleteGrid();
|
|
|
|
setBlendType(RenderObject::BLEND_DEFAULT);
|
|
alpha.stop();
|
|
alpha = 1;
|
|
|
|
elementEffectIndex = eidx;
|
|
|
|
ElementEffect e = dsq->getElementEffectByIndex(eidx);
|
|
|
|
switch(e.type)
|
|
{
|
|
case EFX_SEGS:
|
|
{
|
|
setSegs(e.segsx, e.segsy, e.segs_dgox, e.segs_dgoy, e.segs_dgmx, e.segs_dgmy, e.segs_dgtm, e.segs_dgo);
|
|
setStatic(false);
|
|
}
|
|
break;
|
|
case EFX_ALPHA:
|
|
{
|
|
setBlendType(e.blendType);
|
|
alpha = e.alpha;
|
|
setStatic(false);
|
|
}
|
|
break;
|
|
case EFX_WAVY:
|
|
{
|
|
/*
|
|
char buf[256];
|
|
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);
|
|
float bity = float(getHeight())/float(e.segsy);
|
|
for (int i = 0; i < wavy.size(); i++)
|
|
{
|
|
wavy[i] = Vector(0, -(i*bity));
|
|
}
|
|
//wavySave = wavy;
|
|
wavyRadius = e.wavy_radius;
|
|
wavyFlip = e.wavy_flip;
|
|
wavyMin = bity;
|
|
wavyMax = bity*1.2f;
|
|
|
|
//wavyRadius = 8;
|
|
|
|
createGrid(2, e.segsy);
|
|
|
|
setGridFromWavy();
|
|
|
|
//createGrid(8,8);
|
|
/*
|
|
wavyMin = e.wavy_min;
|
|
wavyMax = e.wavy_max;
|
|
*/
|
|
setStatic(false);
|
|
}
|
|
break;
|
|
default:
|
|
setStatic(true);
|
|
break;
|
|
}
|
|
elementEffectType = e.type;
|
|
}
|
|
|
|
void Element::render()
|
|
{
|
|
if (!elementActive) return;
|
|
#ifdef AQUARIA_BUILD_SCENEEDITOR
|
|
if (dsq->game->isSceneEditorActive() && this->bgLayer == dsq->game->sceneEditor.bgLayer
|
|
&& dsq->game->sceneEditor.editType == ET_ELEMENTS)
|
|
{
|
|
renderBorderColor = Vector(0.5,0.5,0.5);
|
|
if (!dsq->game->sceneEditor.selectedElements.empty())
|
|
{
|
|
for (int i = 0; i < dsq->game->sceneEditor.selectedElements.size(); i++)
|
|
{
|
|
if (this == dsq->game->sceneEditor.selectedElements[i])
|
|
renderBorderColor = Vector(1,1,1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (dsq->game->sceneEditor.editingElement == this)
|
|
renderBorderColor = Vector(1,1,1);
|
|
}
|
|
renderBorder = true;
|
|
//errorLog("!^!^$");
|
|
}
|
|
#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;
|
|
}
|
|
|
|
void Element::fillGrid()
|
|
{
|
|
if (life == 1 && elementActive)
|
|
{
|
|
if (elementFlag == EF_SOLID)
|
|
{
|
|
dsq->game->fillGridFromQuad(this, OT_INVISIBLE, true);
|
|
}
|
|
else if (elementFlag == EF_HURT)
|
|
{
|
|
dsq->game->fillGridFromQuad(this, OT_HURT, false);
|
|
}
|
|
else if (elementFlag == EF_SOLID2)
|
|
{
|
|
dsq->game->fillGridFromQuad(this, OT_INVISIBLE, false);
|
|
}
|
|
else if (elementFlag == EF_SOLID3)
|
|
{
|
|
dsq->game->fillGridFromQuad(this, OT_INVISIBLEIN, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|