1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-07-03 06:24:32 +00:00

Merge branch 'experimental'

Conflicts:
	BBGE/Shader.cpp
This commit is contained in:
fgenesis 2013-06-24 02:48:17 +02:00
commit 93abd03c27
67 changed files with 2061 additions and 1000 deletions

View file

@ -1074,7 +1074,9 @@ void AnimationEditor::applyTranslation()
{
int xdiff = editingBone->position.x - bcur->x;
int ydiff = editingBone->position.y - bcur->y;
// all bones mode
if(!core->getCtrlState())
{
// all bones in one anim mode
for (int i = 0; i < editSprite->getCurrentAnimation()->getNumKeyframes(); ++i)
{
BoneKeyframe *b = editSprite->getCurrentAnimation()->getKeyframe(i)->getBoneKeyframe(editingBone->boneIdx);
@ -1085,6 +1087,23 @@ void AnimationEditor::applyTranslation()
}
}
}
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->x += xdiff;
b->y += ydiff;
}
}
}
}
}
}
}
}
@ -1187,6 +1206,8 @@ void AnimationEditor::rmbu()
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);
@ -1196,6 +1217,22 @@ void AnimationEditor::rmbu()
}
}
}
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 += rotdiff;
}
}
}
}
}
}
}
}

View file

@ -569,8 +569,7 @@ void AquariaKeyConfig::onUpdate(float dt)
if (!ai)
{
errorLog("Could not find actionInput: " + actionInputName);
exit(-1);
exit_error("Could not find actionInput: " + actionInputName);
}
switch(inputSetType)
{
@ -589,14 +588,6 @@ void AquariaKeyConfig::onUpdate(float dt)
}
}
/*
if (k == 0)
{
errorLog("AquariaKeyConfig::onUpdate");
exit(-1);
}
*/
int *value = 0;
if (inputSetType == INPUTSET_OTHER)

View file

@ -120,6 +120,12 @@ const float NOTE_ACCEPT_ANGLE_OFFSET = 15;
const int COLLIDE_RADIUS_NORMAL = 10;
const int COLLIDE_RADIUS_FISH = 8;
const int COLLIDE_RANGE_NORMAL = 2;
const int COLLIDE_RANGE_FISH = 1;
const float COLLIDE_MOD_NORMAL = 1.0f;
const float COLLIDE_MOD_FISH = 0.1f;
const int requiredDualFormCharge = 3;
bool usingDigital = false;
@ -744,7 +750,7 @@ void Avatar::toggleMovement(bool on)
bool Avatar::isLockable()
{
return (bursting || !_isUnderWater) && (boneLockDelay == 0) && (dsq->continuity.form != FORM_FISH);
return (bursting || !_isUnderWater) && (boneLockDelay == 0) && canLockToWall();
}
bool Avatar::isSinging()
@ -752,11 +758,6 @@ bool Avatar::isSinging()
return singing;
}
void Avatar::shift()
{
dsq->continuity.shiftWorlds();
}
void Avatar::applyWorldEffects(WorldType type)
{
static bool oldfh=false;
@ -1595,6 +1596,8 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF
//rotationOffset.interpolateTo(Vector(0,0,0), 0.5);
collideRadius = COLLIDE_RADIUS_NORMAL;
setCanLockToWall(true);
setCollisionAvoidanceData(COLLIDE_RANGE_NORMAL, COLLIDE_MOD_NORMAL);
}
break;
case FORM_SUN:
@ -1606,9 +1609,13 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF
position = bodyPosition;
dsq->continuity.warpLiToAvatar();
spiritBeaconEmitter.start();
setCanActivateStuff(true);
setCanLockToWall(true);
setCanBurst(true);
setDamageTarget(DT_WALLHURT, true);
break;
case FORM_BEAST:
//dsq->game->sceneColor3.interpolateTo(Vector(1, 1, 1), 0.5);
setCanSwimAgainstCurrents(false);
break;
case FORM_DUAL:
if (dsq->continuity.hasLi())
@ -1618,6 +1625,9 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF
dsq->game->li->setState(STATE_IDLE);
}
break;
case FORM_NATURE:
setDamageTarget(DT_WALLHURT, true);
break;
default:
if (leftHandEmitter && rightHandEmitter)
{
@ -1727,6 +1737,8 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF
//refreshModel("NaijaFish", "");
collideRadius = COLLIDE_RADIUS_FISH;
setCanLockToWall(false);
setCollisionAvoidanceData(COLLIDE_RANGE_FISH, COLLIDE_MOD_FISH);
}
break;
case FORM_SUN:
@ -1758,42 +1770,13 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF
hair->setTexture("Naija/Cape-NatureForm");
hair->alphaMod = 1.0;
}
/*
skeletalSprite.loadSkin("ChildTeira");
refreshModel();
*/
/*
if (dsq->game->sceneNatureForm == "forest")
{
debugLog("Forest Form");
dsq->continuity.form = FORM_NATURE_FOREST;
}
else if (dsq->game->sceneNatureForm == "sun")
{
dsq->continuity.form = FORM_NATURE_SUN;
debugLog("Sun Form");
}
else if (dsq->game->sceneNatureForm == "fire")
{
dsq->continuity.form = FORM_NATURE_FIRE;
debugLog("Fire Form");
}
else if (dsq->game->sceneNatureForm == "dark")
{
dsq->continuity.form = FORM_NATURE_DARK;
debugLog("Dark Form");
}
else if (dsq->game->sceneNatureForm == "rock" || dsq->game->sceneNatureForm.empty())
{
dsq->continuity.form = FORM_NATURE_ROCK;
debugLog("Rock Form");
}
*/
setDamageTarget(DT_WALLHURT, false);
break;
case FORM_BEAST:
{
refreshModel("Naija", "BeastForm");
setCanSwimAgainstCurrents(true);
}
break;
case FORM_SPIRIT:
@ -1801,6 +1784,10 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF
bodyOffset = offset;
fallOffWall();
dsq->continuity.shiftWorlds();
setCanActivateStuff(false);
setCanLockToWall(false);
setCanBurst(false);
setDamageTarget(DT_WALLHURT, false);
if (onInit)
{
@ -2171,7 +2158,8 @@ void Avatar::loseTargets()
void Avatar::updateTargetQuads(float dt)
{
particleManager->setSuckPosition(1, dsq->getGameCursorPosition());
const Vector cursorpos = dsq->getGameCursorPosition();
particleManager->setSuckPosition(1, cursorpos);
/*
for (int i = 0; i < targetQuads.size(); i++)
@ -2202,7 +2190,8 @@ void Avatar::updateTargetQuads(float dt)
targets[i].pos = e->getTargetPoint(targets[i].targetPt);
if (i == 0)
{
particleManager->setSuckPosition(1, targets[i].pos);
particleManager->setSuckPosition(1, targets[i].pos); // suckpos 1 is overridden elsewhere later
particleManager->setSuckPosition(2, targets[i].pos);
}
/*
@ -2215,7 +2204,7 @@ void Avatar::updateTargetQuads(float dt)
}
else
{
targetQuads[i]->position = dsq->getGameCursorPosition();
targetQuads[i]->position = cursorpos;
//targetQuads[i]->alpha.interpolateTo(0, 0.1);
}
}
@ -2235,7 +2224,7 @@ void Avatar::updateTargetQuads(float dt)
debugLog(os.str());
*/
targetQuads[i]->position = dsq->getGameCursorPosition();
targetQuads[i]->position = cursorpos;
if (dsq->continuity.form == FORM_ENERGY && isInputEnabled())
{
if (dsq->inputMode == INPUT_JOYSTICK && targetQuads[i]->isRunning())
@ -3495,8 +3484,8 @@ void Avatar::lockToWallCommon()
void Avatar::lockToWall()
{
if (riding) return;
if (inCurrent && dsq->continuity.form != FORM_BEAST) return;
if (dsq->continuity.form == FORM_FISH || dsq->continuity.form == FORM_SPIRIT) return;
if (inCurrent && !canSwimAgainstCurrents()) return;
if (!canLockToWall()) return;
if (state.lockedToWall) return;
if (vel.x == 0 && vel.y == 0) return;
if (dsq->game->isPaused()) return;
@ -3594,7 +3583,7 @@ void Avatar::lockToWall()
}
}
if (dsq->game->getGrid(t)==OT_HURT && dsq->continuity.form != FORM_NATURE)
if (dsq->game->getGrid(t)==OT_HURT && isDamageTarget(DT_WALLHURT))
{
good = false;
}
@ -4128,6 +4117,18 @@ Avatar::Avatar() : Entity(), ActionMapper()
collideRadius = COLLIDE_RADIUS_FISH;
else
collideRadius = COLLIDE_RADIUS_NORMAL;
// defaults for normal form
_canActivateStuff = true;
_canBurst = true;
_canLockToWall = true;
_canSwimAgainstCurrents = false;
_canCollideWithShots = true;
_collisionAvoidMod = COLLIDE_MOD_NORMAL;
_collisionAvoidRange = COLLIDE_RANGE_NORMAL;
_seeMapMode = SEE_MAP_DEFAULT;
}
void Avatar::revert()
@ -4324,7 +4325,7 @@ void Avatar::startBurstCommon()
void Avatar::startBurst()
{
if (!riding && dsq->continuity.form != FORM_SPIRIT && (joystickMove || getVectorToCursor().getSquaredLength2D() > sqr(BURST_DISTANCE))
if (!riding && canBurst() && (joystickMove || getVectorToCursor().getSquaredLength2D() > sqr(BURST_DISTANCE))
&& getState() != STATE_PUSH && (!skeletalSprite.getCurrentAnimation() || (skeletalSprite.getCurrentAnimation()->name != "spin"))
&& _isUnderWater && !isActing(ACTION_ROLL))
{
@ -4686,6 +4687,35 @@ void Avatar::action(int id, int state)
}
}
void Avatar::doBindSong()
{
if (pullTarget)
{
pullTarget->stopPull();
pullTarget = 0;
core->sound->playSfx("Denied");
}
else
{
dsq->game->bindIngredients();
setNearestPullTarget();
if (!pullTarget)
{
core->sound->playSfx("Denied");
}
else
{
core->sound->playSfx("Bind");
}
}
}
void Avatar::doShieldSong()
{
core->sound->playSfx("Shield-On");
activateAura(AURA_SHIELD);
}
void Avatar::render()
{
@ -4858,10 +4888,6 @@ void Avatar::clampVelocity()
}
}
if (!inCurrent || (inCurrent && withCurrent))
{
if (dsq->continuity.form == FORM_FISH)
@ -4885,13 +4911,9 @@ void Avatar::clampVelocity()
}
setMaxSpeed(currentMaxSpeed * useSpeedMult);
//float cheatLen = vel.getSquaredLength2D();
vel.capLength2D(getMaxSpeed());
/*
if (cheatLen > sqr(getMaxSpeed()))
vel.setLength2D(getMaxSpeed());
*/
setMaxSpeed(currentMaxSpeed * useSpeedMult * dsq->continuity.speedMult2);
vel.capLength2D(getMaxSpeed() * maxSpeedLerp.x);
}
void Avatar::activateAura(AuraType aura)
@ -5246,7 +5268,7 @@ void Avatar::updateWallJump(float dt)
void Avatar::updateRoll(float dt)
{
if (!inputEnabled || dsq->continuity.getWorldType() == WT_SPIRIT)
if (!inputEnabled || dsq->game->isWorldPaused())
{
if (rolling)
stopRoll();
@ -5385,7 +5407,18 @@ void Avatar::setWasUnderWater()
bool Avatar::canActivateStuff()
{
return dsq->continuity.form != FORM_SPIRIT;
return _canActivateStuff;
}
void Avatar::setCanActivateStuff(bool on)
{
_canActivateStuff = on;
}
void Avatar::setCollisionAvoidanceData(int range, float mod)
{
_collisionAvoidRange = range;
_collisionAvoidMod = mod;
}
bool Avatar::canQuickSong()
@ -5705,38 +5738,6 @@ void Avatar::onUpdate(float dt)
}
// setup shader
if (core->afterEffectManager)
{
/*
if (!_isUnderWater)
{
core->afterEffectManager->setActiveShader(AS_WASHOUT);
//core->afterEffectManager->setActiveShader(AS_NONE);
}
else
*/
if (dsq->user.video.shader != AS_NONE)
{
core->afterEffectManager->setActiveShader((ActiveShader)dsq->user.video.shader);
}
else
{
if (damageTimer.isActive() && dsq->isShakingCamera())
{
if (dsq->user.video.blur)
core->afterEffectManager->setActiveShader(AS_BLUR);
}
else
{
core->afterEffectManager->setActiveShader(AS_NONE);
}
}
}
Entity::onUpdate(dt);
if (isEntityDead() && skeletalSprite.getCurrentAnimation()->name != "dead")
@ -6176,7 +6177,7 @@ void Avatar::onUpdate(float dt)
//if (core->getNestedMains() == 1)
{
if (getState() != STATE_TRANSFORM && dsq->continuity.getWorldType() == WT_NORMAL)
if (getState() != STATE_TRANSFORM && !dsq->game->isWorldPaused())
{
formAbilityUpdate(dt);
}
@ -6410,7 +6411,7 @@ void Avatar::onUpdate(float dt)
}
}
if (!state.lockedToWall && _isUnderWater && dsq->continuity.getWorldType() == WT_NORMAL && canMove)
if (!state.lockedToWall && _isUnderWater && !dsq->game->isWorldPaused() && canMove)
{
if (bursting)
{
@ -6466,13 +6467,9 @@ void Avatar::onUpdate(float dt)
if (getState() != STATE_PUSH && !state.lockedToWall && inputEnabled && _isUnderWater && canMove)
{
float a = 800*dt;
Vector lastVel = vel;
Vector addVec;
bool isMovingSlow = false;
static Vector lastMousePos;
Vector pos = lastMousePos - dsq->getGameCursorPosition();
static bool lastDown;
float len = 0;
@ -6480,8 +6477,6 @@ void Avatar::onUpdate(float dt)
_isUnderWater && !riding && !boneLock.on &&
(movingOn || ((dsq->inputMode == INPUT_JOYSTICK || dsq->inputMode== INPUT_KEYBOARD) || (core->mouse.buttons.left || bursting))))
{
//addVec = getVectorToCursorFr
//(dsq->inputMode != INPUT_JOYSTICK && dsq->inputMode != INPUT_KEYBOARD)
if (dsq->inputMode == INPUT_MOUSE || !this->singing)
{
addVec = getVectorToCursorFromScreenCentre();//getVectorToCursor();
@ -6506,23 +6501,11 @@ void Avatar::onUpdate(float dt)
addVec = Vector(0,0,0);
}
/*
if (!core->mouse.buttons.left && bursting)
{
addVec = vel;
}
*/
if (!addVec.isLength2DIn(minMouse))
{
//if (core->mouse.buttons.left)
{
len = addVec.getLength2D();
// addVec is always overwritten below; I assume this is old code? --achurch
//if (len > 200)
// addVec.setLength2D(a *10);
if (len > 100)
addVec.setLength2D(a *2);
else
@ -6556,31 +6539,11 @@ void Avatar::onUpdate(float dt)
stopBurst();
}
}
//vel = Vector(0,0,0);
}
addVec = Vector(0,0,0);
}
}
//addVec |= a;
/*
if (pos.getSquaredLength2D() > 10000)
{
startBurst();
}
*/
}
else
{
}
lastDown = core->mouse.buttons.left;
/*
std::ostringstream os;
os << "addVec(" << addVec.x << ", " << addVec.y << ")";
debugLog(os.str());
*/
lastMousePos = dsq->getGameCursorPosition();
if (!rolling && !state.backFlip && !flourish)
{
@ -6613,20 +6576,6 @@ void Avatar::onUpdate(float dt)
}
}
/*
// HACK: joystick code / slow
if (addVec.x == 0 && addVec.y == 0)
{
float jpos[2];
glfwGetJoystickPos(GLFW_JOYSTICK_1, jpos, 2);
const float deadZone = 0.1;
if (fabsf(jpos[0]) > deadZone || fabsf(jpos[1]) > deadZone)
addVec = Vector(jpos[0]*a, -jpos[1]*a);
}
*/
// will not get here if not underwater
if (isLockable())
lockToWall();
@ -6634,18 +6583,10 @@ void Avatar::onUpdate(float dt)
{
currentMaxSpeed=0;
vel += addVec;
//addVec |= a;
//float cheatLen = vel.getSquaredLength2D();
if (bursting)
{
Vector add = addVec;
/*
// HACK: this will let the player boost in one direction while turning to face another
if (!core->mouse.buttons.left)
{
add = vel;
}
*/
add.setLength2D(BURST_ACCEL*dt);
vel += add;
@ -6663,33 +6604,16 @@ void Avatar::onUpdate(float dt)
{
if (isActing(ACTION_SLOW) || isMovingSlow)
{
/*
int spdRange = maxMouse - minMouse;
float p = (len - minMouse) / spdRange;
int spd = p * vars->maxSwimSpeed;// + minMouse
currentMaxSpeed = spd;
*/
currentMaxSpeed = vars->maxSlowSwimSpeed;
}
//else if (dsq->continuity.getWorldType() == WT_NORMAL)
else
currentMaxSpeed = vars->maxSwimSpeed;
/*
else
currentMaxSpeed = vars->maxDreamWorldSpeed;
*/
}
}
/*
if (dsq->continuity.form == FORM_SPIRIT)
currentMaxSpeed *= 0.5f;
*/
if (leaches > 0)
{
currentMaxSpeed -= leaches*60;
// vel |= vel.getLength2D()-1*leaches;
}
if (state.blind)
@ -6698,19 +6622,6 @@ void Avatar::onUpdate(float dt)
if (currentMaxSpeed < 0)
currentMaxSpeed = 1;
/*
if (inCurrent)
{
ropeState = 0;
currentMaxSpeed = 1200;
}
*/
//clampVelocity();
//float angle;
if (getState() == STATE_TRANSFORM)
rotateToVec(addVec, 0.1, 90);
else
@ -6738,13 +6649,6 @@ void Avatar::onUpdate(float dt)
}
else
{
/*
if (bursting && !core->mouse.buttons.left)
{
}
else
rotateToVec(addVec, 0.1);
*/
if (!state.nearWall && !flourish)
rotateToVec(addVec, 0.1);
}
@ -7054,13 +6958,9 @@ void Avatar::onUpdate(float dt)
}
if (!state.lockedToWall && !bursting && _isUnderWater && swimming && !isFollowingPath())
if (!state.lockedToWall && !bursting && _isUnderWater && swimming && !isFollowingPath() && _collisionAvoidRange > 0)
{
//debugLog("collision avoidance");
if (dsq->continuity.form == FORM_FISH)
doCollisionAvoidance(dt, 1, 0.1, 0, 800, OT_HURT);
else
doCollisionAvoidance(dt, 2, 1.0, 0, 800, OT_HURT);
doCollisionAvoidance(dt, _collisionAvoidRange, _collisionAvoidMod, 0, 800, OT_HURT);
}
if (!game->isShuttingDownGameState())
@ -7077,7 +6977,11 @@ void Avatar::onUpdate(float dt)
{
/*collideCheck:*/
if (vel.getLength2D() < sqr(2))
// Beware: This code may cause clamping vel to zero if the framerate is very high.
// Starting with zero vel, low difftimes will cause an addVec small enough that this
// check will always trigger, and vel will never get larger than zero.
// Under water and swimming check should hopefully prevent this from happening. -- FG
if (_isUnderWater && !isSwimming() && vel.getLength2D() < sqr(2))
{
vel = Vector(0,0,0);
}
@ -7118,7 +7022,6 @@ void Avatar::onUpdate(float dt)
else
omov -= mov;
lastLastPosition = position;
lastPosition = position;
Vector newPosition = position + mov;
//Vector testPosition = position + (vel *dt)*2;
@ -7127,11 +7030,11 @@ void Avatar::onUpdate(float dt)
if (dsq->game->collideCircleWithGrid(position, collideRadius))
{
if (dsq->game->lastCollideTileType == OT_HURT
&& dsq->continuity.getWorldType() != WT_SPIRIT
&& dsq->continuity.form != FORM_NATURE)
&& isDamageTarget(DT_WALLHURT))
{
DamageData d;
d.damage = 1;
d.damageType = DT_WALLHURT;
damage(d);
vel2 = Vector(0,0,0);
//doCollisionAvoidance(1, 3, 1);
@ -7294,6 +7197,7 @@ void Avatar::onUpdate(float dt)
rightHandEmitter->position = boneRightHand->getWorldCollidePosition(Vector(0,16));
}
if(canCollideWithShots())
dsq->game->handleShotCollisions(this, (activeAura == AURA_SHIELD));
}
@ -7314,7 +7218,7 @@ void Avatar::checkNearWall()
{
t.x = oT.x + v.x*i;
t.y = oT.y + v.y*i;
if (dsq->game->isObstructed(t) && dsq->game->getGrid(t) != OT_HURT)
if (dsq->game->isObstructed(t, ~OT_HURT))
{
obs = true;
break;

View file

@ -66,6 +66,13 @@ enum AvatarAnimLayers
ANIMLAYER_MAX
};
enum SeeMapMode
{
SEE_MAP_NEVER = 0,
SEE_MAP_DEFAULT = 1,
SEE_MAP_ALWAYS = 2,
};
class SongIconParticle : public Quad
{
public:
@ -160,7 +167,6 @@ public:
Entity *entityToActivate;
Path *pathToActivate;
void shift();
void applyWorldEffects(WorldType type);
void toggleMovement(bool on);
@ -284,6 +290,7 @@ public:
void endOfGameState();
bool canQuickSong();
bool canActivateStuff();
void setCanActivateStuff(bool on);
bool hasThingToActivate();
float biteTimer;
@ -317,8 +324,28 @@ public:
bool canSetBoneLock();
void revert();
void doBindSong();
void doShieldSong();
bool canBurst() const { return _canBurst; }
void setCanBurst(bool b) { _canBurst = b; }
bool canLockToWall() const { return _canLockToWall; }
void setCanLockToWall(bool b) { _canLockToWall = b; }
bool canSwimAgainstCurrents() const { return _canSwimAgainstCurrents; }
void setCanSwimAgainstCurrents(bool b) { _canSwimAgainstCurrents = b; }
bool canCollideWithShots() const { return _canCollideWithShots; }
void setCollideWithShots(bool b) { _canCollideWithShots = b; }
void setCollisionAvoidanceData(int range, float mod);
void setSeeMapMode(SeeMapMode mode) { _seeMapMode = mode; }
SeeMapMode getSeeMapMode() const { return _seeMapMode; }
int leaches;
float shieldPoints;
protected:
void setSongIconPositions();
@ -359,8 +386,6 @@ protected:
Vector fallGravity;
int lastOutOfWaterMaxSpeed;
int shieldPoints;
void onIdle();
void onHeal(int type);
ParticleEffect biteLeftEmitter, biteRightEmitter, swimEmitter, auraHitEmitter;
@ -450,7 +475,15 @@ protected:
void lockToWall();
void doShock(const std::string &shotName);
Vector lastLastPosition;
bool _canActivateStuff;
bool _canBurst;
bool _canLockToWall;
bool _canSwimAgainstCurrents;
bool _canCollideWithShots;
SeeMapMode _seeMapMode;
int _collisionAvoidRange;
float _collisionAvoidMod;
};

View file

@ -142,7 +142,7 @@ void Beam::render()
void Beam::onRender()
{
#ifdef BBGE_BUILD_OPENGL
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
Vector diff = endPos - position;
Vector side = diff;
//side.normalize2D();

View file

@ -61,7 +61,7 @@ bool Continuity::isIngredientFull(IngredientData *data)
{
if (nocasecmp(ingredients[i]->name, data->name)==0)
{
if (ingredients[i]->amount >= MAX_INGREDIENT_AMOUNT)
if (ingredients[i]->amount >= ingredients[i]->maxAmount)
return true;
else
return false;
@ -70,8 +70,9 @@ bool Continuity::isIngredientFull(IngredientData *data)
return false;
}
void Continuity::pickupIngredient(IngredientData *d, int amount, bool effects)
void Continuity::pickupIngredient(IngredientData *d, int amount, bool effects, bool learn)
{
if(learn)
learnRecipe(d->name, effects);
if (!getIngredientHeldByName(d->name))
@ -79,13 +80,13 @@ void Continuity::pickupIngredient(IngredientData *d, int amount, bool effects)
ingredients.push_back(d);
}
if (d->amount < MAX_INGREDIENT_AMOUNT - amount)
if (d->amount < d->maxAmount - amount)
{
d->amount += amount;
}
else
{
d->amount = MAX_INGREDIENT_AMOUNT;
d->amount = d->maxAmount;
}
}
@ -607,8 +608,10 @@ std::string Continuity::getAllIEString(IngredientData *data)
return os.str();
}
void Continuity::applyIngredientEffects(IngredientData *data)
// returns true if eaten
bool Continuity::applyIngredientEffects(IngredientData *data)
{
bool eaten = true;
float y =0;
for (int i = 0; i < data->effects.size(); i++)
{
@ -841,28 +844,37 @@ void Continuity::applyIngredientEffects(IngredientData *data)
// this item should only affect li if naija drops it and li eats it.
}
break;
case IET_SCRIPT:
{
// If this fails, it will still be eaten
if(dsq->game->cookingScript)
dsq->game->cookingScript->call("useIngredient", data->name.c_str(), &eaten);
}
break;
default:
{
char str[256];
sprintf((char*)&str, "ingredient effect not defined, index[%d]", int(useType));
errorLog(str);
eaten = false;
}
break;
}
}
return eaten;
}
std::string Continuity::getIngredientAffectsString(IngredientData *data)
{
/*
std::string str;
for (int i = 0; i < data->effects.size(); i++)
if(data->type == IET_SCRIPT)
{
str += splitCamelCase(getIngredientDescription(data->effects[i].type)) + "\n";
if(dsq->game->cookingScript)
{
std::string ret = "";
dsq->game->cookingScript->call("getIngredientString", data->name.c_str(), &ret);
return ret;
}
}
return str;
*/
return getAllIEString(data);
}
@ -910,6 +922,43 @@ void Continuity::clearIngredientData()
ingredientData.clear();
}
void Continuity::loadIngredientData()
{
if(ingredients.size())
{
debugLog("Can't reload ingredient data, inventory is not empty");
return; // ... because otherwise there would be dangling pointers and it would crash.
}
clearIngredientData();
ingredientDescriptions.clear();
ingredientDisplayNames.clear();
recipes.clear();
loadIngredientDisplayNames("data/ingredientnames.txt");
std::string fname = localisePath("data/ingredientnames.txt");
loadIngredientDisplayNames(fname);
if(dsq->mod.isActive())
{
fname = localisePath(dsq->mod.getPath() + "ingredientnames.txt", dsq->mod.getPath());
loadIngredientDisplayNames(fname);
}
if(dsq->mod.isActive())
{
//load mod ingredients
loadIngredientData(dsq->mod.getPath() + "ingredients.txt");
}
//load ingredients for the main game
if(ingredientData.empty() && recipes.empty())
{
loadIngredientData("data/ingredients.txt");
}
}
void Continuity::loadIngredientData(const std::string &file)
{
std::string line, name, gfx, type, effects;
@ -920,6 +969,7 @@ void Continuity::loadIngredientData(const std::string &file)
InStream in(file.c_str());
bool recipes = false;
bool extradata = false;
while (std::getline(in, line))
{
std::istringstream inLine(line);
@ -931,6 +981,11 @@ void Continuity::loadIngredientData(const std::string &file)
recipes = true;
break;
}
else if(name == "==Extra==")
{
extradata = true;
break;
}
inLine >> gfx >> type;
std::getline(inLine, effects);
@ -1032,6 +1087,10 @@ void Continuity::loadIngredientData(const std::string &file)
{
fx.type = IET_LI;
}
else if (bit.find("script") != std::string::npos)
{
fx.type = IET_SCRIPT;
}
int c = 0;
while (c < bit.size())
@ -1052,6 +1111,31 @@ void Continuity::loadIngredientData(const std::string &file)
ingredientData.push_back(data);
}
if(extradata)
{
while (std::getline(in, line))
{
SimpleIStringStream inLine(line.c_str(), SimpleIStringStream::REUSE);
int maxAmount = MAX_INGREDIENT_AMOUNT;
int rotKind = 1;
inLine >> name >> maxAmount >> rotKind;
if (name == "==Recipes==")
{
recipes = true;
break;
}
IngredientData *data = getIngredientDataByName(name);
if(!data)
{
errorLog("Specifying data for undefined ingredient: " + name);
continue;
}
data->maxAmount = maxAmount;
data->rotKind = rotKind;
}
}
if (recipes)
{
bool quitNext = false;
@ -1347,16 +1431,6 @@ Song *Continuity::getSongByIndex(int idx)
return &songBank[idx];
}
int Continuity::getSongBankSize()
{
int c = 0;
for (SongMap::iterator i = songBank.begin(); i != songBank.end(); i++)
{
c++;
}
return c;
}
void Continuity::castSong(int num)
{
if (!dsq->continuity.hasSong((SongType)num)) return;
@ -1409,32 +1483,10 @@ void Continuity::castSong(int num)
switch((SongType)num)
{
case SONG_SHIELDAURA:
core->sound->playSfx("Shield-On");
dsq->game->avatar->activateAura(AURA_SHIELD);
dsq->game->avatar->doShieldSong();
break;
case SONG_BIND:
//debugLog("sang pull");
if (dsq->game->avatar->pullTarget)
{
dsq->game->avatar->pullTarget->stopPull();
dsq->game->avatar->pullTarget = 0;
core->sound->playSfx("Denied");
}
else
{
dsq->game->bindIngredients();
dsq->game->avatar->setNearestPullTarget();
if (!dsq->game->avatar->pullTarget)
{
core->sound->playSfx("Denied");
}
else
{
core->sound->playSfx("Bind");
}
}
//dsq->game->avatar->openPullTargetInterface();
//pickingPullTarget = true;
dsq->game->avatar->doBindSong();
break;
case SONG_ENERGYFORM:
dsq->game->avatar->changeForm(FORM_ENERGY);
@ -1948,9 +2000,15 @@ void Continuity::shiftWorlds()
{
WorldType lastWorld = worldType;
if (worldType == WT_NORMAL)
{
worldType = WT_SPIRIT;
dsq->game->setWorldPaused(true);
}
else if (worldType == WT_SPIRIT)
{
worldType = WT_NORMAL;
dsq->game->setWorldPaused(false);
}
FOR_ENTITIES(i)
{
Entity *e = *i;
@ -2336,15 +2394,34 @@ void Continuity::saveFile(int slot, Vector position, unsigned char *scrShotData,
if (hasUserString)
os << spacesToUnderscores((*i).userString) << " ";
/*
std::ostringstream os2;
os2 << "Saving a Gem called [" << (*i).name << "] with userString [" << (*i).userString << "] pos (" << (*i).pos.x << ", " << (*i).pos.y << ")\n";
os2 << os.str() << "\n";
debugLog(os2.str());
*/
}
gems.SetAttribute("c", os.str());
// This is the format used in the android version. Keeping this commented out for now,
// but it should be used instead of the code above in some time -- FG
/*
os.str("");
bool hasMapName = false;
os << this->gems.size() << " ";
for (Gems::iterator i = this->gems.begin(); i != this->gems.end(); i++)
{
os << (*i).name << " ";
hasMapName = !(*i).mapName.empty();
os << hasMapName << " ";
if(hasMapName)
os << (*i).mapName << " "; // warning: this will fail to load if the map name contains whitespace
os << (*i).pos.x << " " << (*i).pos.y << " ";
os << (*i).canMove << " ";
hasUserString = !(*i).userString.empty();
os << hasUserString << " ";
if (hasUserString)
os << spacesToUnderscores((*i).userString) << " ";
}
gems.SetAttribute("d", os.str());
*/
}
doc.InsertEndChild(gems);
@ -2441,6 +2518,7 @@ void Continuity::saveFile(int slot, Vector position, unsigned char *scrShotData,
startData.SetAttribute("scene", dsq->game->sceneName);
startData.SetAttribute("exp", dsq->continuity.exp);
startData.SetAttribute("h", dsq->continuity.maxHealth);
startData.SetAttribute("ch", dsq->continuity.health);
startData.SetAttribute("naijaModel", dsq->continuity.naijaModel);
startData.SetAttribute("costume", dsq->continuity.costume);
startData.SetAttribute("form", dsq->continuity.form);
@ -2459,6 +2537,16 @@ void Continuity::saveFile(int slot, Vector position, unsigned char *scrShotData,
}
startData.SetAttribute("songs", os2.str());
// new format as used by android version
std::ostringstream ingrNames;
for (int i = 0; i < ingredients.size(); i++)
{
IngredientData *data = ingredients[i];
ingrNames << data->name << " " << data->amount << " ";
}
startData.SetAttribute("ingrNames", ingrNames.str());
// for compatibility with older versions
std::ostringstream ingrOs;
for (int i = 0; i < ingredients.size(); i++)
{
@ -2492,6 +2580,74 @@ void Continuity::saveFile(int slot, Vector position, unsigned char *scrShotData,
}
startData.SetAttribute("intFlags", fos.str());
// Additional data for the android version
#define SINGLE_FLOAT_ATTR(name, cond, val) \
do { if((cond) && (val)) { \
std::ostringstream osf; \
osf << (val); \
startData.SetAttribute(name, osf.str()); \
}} while(0)
SINGLE_FLOAT_ATTR("blind", dsq->game->avatar->state.blind, dsq->game->avatar->state.blindTimer.getValue());
SINGLE_FLOAT_ATTR("invincible", invincibleTimer.isActive(), invincibleTimer.getValue());
SINGLE_FLOAT_ATTR("regen", regenTimer.isActive(), regenTimer.getValue());
SINGLE_FLOAT_ATTR("trip", tripTimer.isActive(), tripTimer.getValue());
SINGLE_FLOAT_ATTR("shieldPoints", true, dsq->game->avatar->shieldPoints);
SINGLE_FLOAT_ATTR("webTimer", webTimer.isActive(), webTimer.getValue()); // Extension; not present in the android version
#undef SINGLE_FLOAT_ATTR
#define TIMER_AND_VALUE_ATTR(name, timer, val) \
do { if(((timer).isActive()) && (val)) { \
std::ostringstream osf; \
osf << (val) << " " << ((timer).getValue()); \
startData.SetAttribute((name), osf.str()); \
}} while(0)
TIMER_AND_VALUE_ATTR("biteMult", biteMultTimer, biteMult);
TIMER_AND_VALUE_ATTR("speedMult", speedMultTimer, speedMult);
TIMER_AND_VALUE_ATTR("defenseMult", defenseMultTimer, defenseMult);
TIMER_AND_VALUE_ATTR("energyMult", energyTimer, energyMult);
TIMER_AND_VALUE_ATTR("petPower", petPowerTimer, petPower);
TIMER_AND_VALUE_ATTR("liPower", liPowerTimer, liPower);
TIMER_AND_VALUE_ATTR("light", lightTimer, light);
#undef TIMER_AND_VALUE_ATTR
if(poisonTimer.isActive())
{
std::ostringstream osp;
osp << poison << " " << poisonTimer.getValue() << " " << poisonBitTimer.getValue();
startData.SetAttribute("poison", osp.str());
}
if(dsq->game->avatar->activeAura != AURA_NONE)
{
std::ostringstream osa;
osa << dsq->game->avatar->activeAura << " " << dsq->game->avatar->auraTimer;
startData.SetAttribute("aura", osa.str());
}
// FIXME: Web is a bit weird. There are 2 webBitTimer variables in use, one in Continuity, one in Avatar.
// Because the avatar one ticks every 0.5 seconds, it will be hardly noticeable if that timer is off.
// So we just use the Continuty timers and hope for the best. -- FG
if(webTimer.isActive() && dsq->game->avatar->web)
{
Web *w = dsq->game->avatar->web;
const int nump = w->getNumPoints();
std::ostringstream osw;
osw << webBitTimer.getValue() << " " << nump << " ";
for(int i = 0; i < nump; ++i)
{
Vector v = w->getPoint(i);
osw << v.x << " " << v.y << " ";
}
startData.SetAttribute("web", osw.str());
}
// end extra android data
doc.InsertEndChild(startData);
@ -2531,6 +2687,9 @@ std::string Continuity::getSaveFileName(int slot, const std::string &pfix)
void Continuity::loadFileData(int slot, TiXmlDocument &doc)
{
std::string teh_file = dsq->continuity.getSaveFileName(slot, "aqs");
if(!exists(teh_file))
teh_file = dsq->continuity.getSaveFileName(slot, "bin");
if (exists(teh_file))
{
unsigned long size = 0;
@ -2568,7 +2727,7 @@ void Continuity::loadFile(int slot)
if (startData->Attribute("mod"))
{
#ifdef AQUARIA_DEMO
exit(-1);
exit_error("The demo version does not support loading savegames from mods, sorry.");
#else
dsq->mod.load(startData->Attribute("mod"));
#endif
@ -2714,6 +2873,7 @@ void Continuity::loadFile(int slot)
this->gems.push_back(g);
}
}
// num [name mapX mapY canMove hasUserString (userString)]
else if (gems->Attribute("c"))
{
std::string s = gems->Attribute("c");
@ -2751,6 +2911,54 @@ void Continuity::loadFile(int slot)
g.userString = underscoresToSpaces(g.userString);
this->gems.push_back(g);
std::ostringstream os;
os << "Loading a Gem called [" << g.name << "] with userString [" << g.userString << "] pos (" << g.pos.x << ", " << g.pos.y << ")\n";
debugLog(os.str());
}
}
// num [name hasMapName (mapName) mapX mapY canMove hasUserString (userString)]
else if (gems->Attribute("d"))
{
std::string s = gems->Attribute("d");
std::istringstream is(s);
int num = 0;
is >> num;
bool hasUserString = false;
bool hasMapName = false;
GemData g;
std::ostringstream os;
os << "continuity num: [" << num << "]" << std::endl;
os << "data: [" << s << "]" << std::endl;
debugLog(os.str());
for (int i = 0; i < num; i++)
{
g.pos = Vector(0,0,0);
g.canMove = false;
g.userString = "";
g.mapName = "";
hasUserString=false;
hasMapName = false;
is >> g.name;
is >> hasMapName;
if(hasMapName)
is >> g.mapName;
is >> g.pos.x >> g.pos.y;
is >> g.canMove;
is >> hasUserString;
if (hasUserString)
is >> g.userString;
g.userString = underscoresToSpaces(g.userString);
this->gems.push_back(g);
std::ostringstream os;
os << "Loading a Gem called [" << g.name << "] with userString [" << g.userString << "] pos (" << g.pos.x << ", " << g.pos.y << ")\n";
debugLog(os.str());
@ -2790,7 +2998,9 @@ void Continuity::loadFile(int slot)
if (!tile)
{
errorLog("tile dummy");
std::ostringstream os;
os << "tile dummy: dropping data for worldmap tile index " << idx;
debugLog(os.str());
tile = &dummy;
}
@ -2833,7 +3043,23 @@ void Continuity::loadFile(int slot)
dsq->continuity.form = FormType(atoi(startData->Attribute("form")));
}
if (startData->Attribute("ingr"))
if (startData->Attribute("ingrNames"))
{
std::istringstream is(startData->Attribute("ingrNames"));
std::string name;
while (is >> name)
{
int amount=0;
is >> amount;
IngredientData *data = getIngredientDataByName(name);
if (data)
{
data->amount = 0;
pickupIngredient(data, amount, false);
}
}
}
else if (startData->Attribute("ingr")) // use this only if ingrNames does not exist.
{
std::istringstream is(startData->Attribute("ingr"));
int idx;
@ -2898,7 +3124,7 @@ void Continuity::loadFile(int slot)
if (startData->Attribute("h"))
{
int read = atoi(startData->Attribute("h"));
float read = strtof(startData->Attribute("h"), NULL);
maxHealth = read;
health = read;
std::ostringstream os;
@ -2911,6 +3137,21 @@ void Continuity::loadFile(int slot)
dsq->game->avatar->health = maxHealth;
}
}
if (startData->Attribute("ch"))
{
float h = strtof(startData->Attribute("ch"), NULL);
health = h;
std::ostringstream os;
os << "CurHealth read as: " << health;
debugLog(os.str());
if (dsq->game->avatar)
{
dsq->game->avatar->health = h;
}
}
if (startData->Attribute("seconds"))
{
std::istringstream is(startData->Attribute("seconds"));
@ -2921,9 +3162,124 @@ void Continuity::loadFile(int slot)
dsq->continuity.costume = startData->Attribute("costume");
}
//dsq->game->positionToAvatar = Vector(500,400);
dsq->game->sceneToLoad = startData->Attribute("scene");
//dsq->game->transitionToScene();
// Additional data introduced in the android version
if(startData->Attribute("blind"))
{
float timer = strtof(startData->Attribute("blind"), NULL);
if(dsq->game->avatar)
dsq->game->avatar->setBlind(timer);
}
if(startData->Attribute("invincible"))
{
float timer = strtof(startData->Attribute("invincible"), NULL);
setInvincible(timer);
}
if(startData->Attribute("regen"))
{
float timer = strtof(startData->Attribute("regen"), NULL);
setRegen(timer);
}
if(startData->Attribute("trip"))
{
float timer = strtof(startData->Attribute("trip"), NULL);
setTrip(timer);
}
if(startData->Attribute("aura"))
{
std::istringstream is(startData->Attribute("aura"));
int type = AURA_NONE;
float timer = 0.0f;
is >> type >> timer;
auraTimer = timer;
auraType = (AuraType)type;
if(dsq->game->avatar)
{
dsq->game->avatar->activateAura((AuraType)type);
dsq->game->avatar->auraTimer = timer;
}
}
if(startData->Attribute("shieldPoints"))
{
float sp = strtof(startData->Attribute("shieldPoints"), NULL);
if(dsq->game->avatar)
dsq->game->avatar->shieldPoints = sp;
}
#define LOAD_MULTI_SIMPLE(attr, mth) \
do { if(startData->Attribute(attr)) \
{ \
std::istringstream is(startData->Attribute(attr)); \
float value = 0.0f, timer = 0.0f; \
is >> value >> timer; \
this->mth(value, timer); \
}} while(0)
LOAD_MULTI_SIMPLE("biteMult", setBiteMultiplier);
LOAD_MULTI_SIMPLE("speedMult", setSpeedMultiplier);
LOAD_MULTI_SIMPLE("defenseMult", setDefenseMultiplier);
LOAD_MULTI_SIMPLE("energyMult", setEnergy);
LOAD_MULTI_SIMPLE("petPower", setPetPower);
LOAD_MULTI_SIMPLE("liPower", setLiPower);
LOAD_MULTI_SIMPLE("light", setLight);
#undef LOAD_MULTI_SIMPLE
if(startData->Attribute("poison"))
{
std::istringstream is(startData->Attribute("poison"));
float p = 0.0f, pt = 0.0f, pbit = 0.0f;
is >> p >> pt >> pbit;
setPoison(p, pt);
poisonBitTimer.start(pbit);
}
// FIXME: the total web time is seemingly not saved in the file.
// Not sure if the calculation of the remaining time is correct.
// Especially because there are two webBitTimer variables in use (in Continuity and Avatar),
// and both of them access the avatar web. It's thus likely that more points were added than intended. -- FG
if(startData->Attribute("web"))
{
std::istringstream is(startData->Attribute("web"));
float wbit = 0.0f;
int nump = 0;
is >> wbit >> nump;
// 2 web points are added in setWeb() by default, so we exclude them from the calculation
float remainTime = webTime - (0.5 * (nump - 2)); // Avatar::webBitTimer ticks every 0.5 secs
if(nump > 1 && remainTime > 0 && dsq->game->avatar)
{
if(!dsq->game->avatar->web)
dsq->game->avatar->createWeb();
Web *w = dsq->game->avatar->web;
for(int i = 0; i < nump; ++i)
{
Vector v;
is >> v.x >> v.y;
if(i < w->getNumPoints())
w->setPoint(i, v);
else
w->addPoint(v);
}
webBitTimer.start(wbit);
webTimer.start(remainTime);
}
}
// This is AFAIK not in the android version, but let's add this for completeness
// and to avoid the mess described above.
if(startData->Attribute("webTimer"))
{
float timer = strtof(startData->Attribute("webTimer"), NULL);
webTimer.start(timer);
}
}
}
@ -3079,6 +3435,7 @@ GemData *Continuity::pickupGem(std::string name, bool effects)
{
GemData g;
g.name = name;
g.mapName = dsq->game->sceneName;
int sz = gems.size();
//HACK: (hacky) using effects to determine the starting position of the gem
@ -3189,6 +3546,7 @@ void Continuity::reset()
//worldMapTiles.clear();
speedMult = biteMult = fishPoison = defenseMult = 1;
speedMult2 = 1;
poison = 0;
energyMult = 0;
light = petPower = 0;
@ -3218,40 +3576,11 @@ void Continuity::reset()
worldMap.load();
ingredients.clear();
naijaEats.clear();
foodSortType = 0;
ingredients.clear();
//load ingredients
ingredientDisplayNames.clear();
loadIngredientDisplayNames("data/ingredientnames.txt");
std::string fname = localisePath("data/ingredientnames.txt");
loadIngredientDisplayNames(fname);
if(dsq->mod.isActive())
{
fname = localisePath(dsq->mod.getPath() + "ingredientnames.txt", dsq->mod.getPath());
loadIngredientDisplayNames(fname);
}
ingredientDescriptions.clear();
ingredientData.clear();
recipes.clear();
if(dsq->mod.isActive())
{
//load mod ingredients
loadIngredientData(dsq->mod.getPath() + "ingredients.txt");
}
//load ingredients for the main game
if(ingredientData.empty() && recipes.empty()) {
loadIngredientData("data/ingredients.txt");
}
loadIngredientData(); // must be after clearing ingredients
loadPetData();

View file

@ -62,7 +62,7 @@ void CurrentRender::onRender()
{
#ifdef BBGE_BUILD_OPENGL
// note: Leave cull_face disabled!?
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
//int qs = 0;
for (Path *p = dsq->game->getFirstPathOfType(PATH_CURRENT); p; p = p->nextOfType)
{
@ -308,7 +308,7 @@ void CurrentRender::onRender()
//glEnd();
}
glEnable(GL_CULL_FACE);
//glEnable(GL_CULL_FACE);
/*
std::ostringstream os;

View file

@ -615,6 +615,7 @@ void DSQ::debugMenu()
core->afterEffectManager->loadShaders();
}
dsq->user.load();
dsq->continuity.loadIngredientData();
}
else if (c == '2')
{
@ -922,12 +923,14 @@ This build is not yet final, and as such there are a couple things lacking. They
// steam gets inited in here
Core::init();
// steam callbacks are inited here
dsq->continuity.init();
dsq->continuity.stringBank.load();
vars = &v;
v.load();
// steam callbacks are inited here
dsq->continuity.init();
// do copy stuff
#ifdef BBGE_BUILD_UNIX
std::string fn;
@ -997,8 +1000,7 @@ This build is not yet final, and as such there are a couple things lacking. They
{
std::ostringstream os;
os << "Aspect ratio for resolution [" << user.video.resx << ", " << user.video.resy << "] not supported.";
errorLog(os.str());
exit(0);
exit_error(os.str());
}
setFilter(dsq_filter);
@ -1041,7 +1043,7 @@ This build is not yet final, and as such there are a couple things lacking. They
if (!createWindow(user.video.resx, user.video.resy, user.video.bits, user.video.full, "Aquaria"))
#endif
{
msg("Failed to create window");
exit_error("Failed to create window");
return;
}
@ -1533,10 +1535,10 @@ This build is not yet final, and as such there are a couple things lacking. They
renderObjectLayerOrder[LR_ENTITIES_MINUS3] = -1;
renderObjectLayerOrder[LR_ENTITIES_MINUS2] = -1;
if (!Entity::blurShader.isLoaded())
/*if (!Entity::blurShader.isLoaded())
{
//Entity::blurShader.load("data/shaders/stan.vert", "data/shaders/hoblur.frag");
}
}*/
setMousePosition(core->center);
@ -2155,7 +2157,6 @@ void DSQ::loadMods()
// first load the packages, then enumerate XMLs
forEachFile(mod.getBaseModPath(), ".aqmod", loadModPackagesCallback, 0);
forEachFile(mod.getBaseModPath(), ".zip", loadModPackagesCallback, 0);
#endif
forEachFile(mod.getBaseModPath(), ".xml", loadModsCallback, 0);
@ -2335,6 +2336,8 @@ void DSQ::playPositionalSfx(const std::string &name, const Vector &position, flo
void DSQ::shutdown()
{
mod.stop();
Network::shutdown();
scriptInterface.shutdown();
@ -4565,6 +4568,10 @@ void DSQ::onUpdate(float dt)
os << " headRot: " << b->rotation.z;
os << std::endl;
os << "fh: " << dsq->game->avatar->isfh() << " fv: " << dsq->game->avatar->isfv() << std::endl;
os << "canActivate: " << dsq->game->avatar->canActivateStuff();
os << " canBurst: " << dsq->game->avatar->canBurst();
os << " canLTW: " << dsq->game->avatar->canLockToWall();
os << " canSAC: " << dsq->game->avatar->canSwimAgainstCurrents() << std::endl;
}
// DO NOT CALL AVATAR-> beyond this point
@ -4577,6 +4584,7 @@ void DSQ::onUpdate(float dt)
os << "altState: " << core->getKeyState(KEY_LALT) << " | " << core->getKeyState(KEY_RALT) << std::endl;
os << "PMFree: " << particleManager->getFree() << " Active: " << particleManager->getNumActive() << std::endl;
os << "cameraPos: (" << dsq->cameraPos.x << ", " << dsq->cameraPos.y << ")" << std::endl;
os << "worldType: " << continuity.getWorldType() << " worldPaused: " << game->isWorldPaused() << std::endl;
os << "voiceTime: " << dsq->sound->getVoiceTime() << " bNat: " << dsq->game->bNatural;
int ca, ma;
dsq->sound->getStats(&ca, &ma);
@ -4591,7 +4599,7 @@ void DSQ::onUpdate(float dt)
if (isDeveloperKeys() && fpsText && cmDebug && cmDebug->alpha == 1)
{
std::ostringstream os;
os << "FPS: " << core->fps << " | ROC: " << core->renderObjectCount;
os << "FPS: " << core->fps << " | ROC: " << core->renderObjectCount << " | RC: " << Core::dbg_numRenderCalls;
os << " | p: " << core->processedRenderObjectCount << " | t: " << core->totalRenderObjectCount;
os << " | s: " << dsq->continuity.seconds;
os << " | evQ: " << core->eventQueue.getSize();

View file

@ -257,6 +257,7 @@ class Mod
{
public:
Mod();
~Mod();
void clear();
void setActive(bool v);
void start();
@ -297,6 +298,7 @@ protected:
std::string name;
std::string path;
Precacher modcache;
};
class AquariaScreenTransition : public ScreenTransition
@ -616,6 +618,7 @@ struct GemData
GemData() { canMove=false; }
std::string name;
std::string userString;
std::string mapName;
bool canMove;
Vector pos;
};
@ -683,6 +686,7 @@ enum IngredientEffectType
IET_POISON = 17,
IET_BLIND = 18,
IET_ALLSTATUS = 19,
IET_SCRIPT = 20,
IET_MAX
};
@ -713,9 +717,11 @@ public:
std::string displayName;
const IngredientType type;
int amount;
int maxAmount;
int held;
int marked;
bool sorted;
bool rotKind;
bool hasIET(IngredientEffectType iet);
typedef std::vector<IngredientEffect> IngredientEffects;
@ -945,7 +951,7 @@ public:
std::string getSaveFileName(int slot, const std::string &pfix);
int maxHealth;
float maxHealth;
float health;
bool hudVisible;
unsigned int exp;
@ -996,7 +1002,6 @@ public:
FormUpgrades formUpgrades;
void loadSongBank();
int getSongBankSize();
void loadIntoSongBank(const std::string &file);
int checkSong(const Song &song);
int checkSongAssisted(const Song &song);
@ -1050,7 +1055,7 @@ public:
std::string getSongNameBySlot(int slot);
void toggleLiCombat(bool t);
void pickupIngredient(IngredientData *i, int amount, bool effects=true);
void pickupIngredient(IngredientData *i, int amount, bool effects=true, bool learn=true);
int indexOfIngredientData(const IngredientData* data) const;
IngredientData *getIngredientHeldByName(const std::string &name) const; // an ingredient that the player actually has; in the ingredients list
IngredientData *getIngredientDataByName(const std::string &name); // an ingredient in the general data list; ingredientData
@ -1058,8 +1063,9 @@ public:
IngredientData *getIngredientHeldByIndex(int idx) const;
IngredientData *getIngredientDataByIndex(int idx);
void applyIngredientEffects(IngredientData *data);
bool applyIngredientEffects(IngredientData *data);
void loadIngredientData();
void loadIngredientData(const std::string &file);
void loadIngredientDisplayNames(const std::string& file);
bool hasIngredients() const { return !ingredients.empty(); }
@ -1098,6 +1104,8 @@ public:
Timer energyTimer, poisonTimer, poisonBitTimer;
Timer webTimer, webBitTimer, lightTimer, petPowerTimer;
float speedMult2;
void eatBeast(const EatData &eatData);
void removeNaijaEat(int idx);
void removeLastNaijaEat();

View file

@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "ScriptedEntity.h"
#include "Shot.h"
Shader Entity::blurShader;
//Shader Entity::blurShader;
void Entity::stopPull()
{
@ -1080,7 +1080,7 @@ void Entity::onFHScale()
copySkel.alpha.interpolateTo(0, 0.5);
*/
//skeletalSprite.alpha.interpolateTo(1,sct);
blurShaderAnim.interpolateTo(Vector(blurMin,0,0), sct);
//blurShaderAnim.interpolateTo(Vector(blurMin,0,0), sct);
fhScale = 0;
}
@ -1105,8 +1105,8 @@ void Entity::onFH()
flipScale.interpolateTo(Vector(0.6, 1), sct);
blurShaderAnim = Vector(blurMin);
blurShaderAnim.interpolateTo(Vector(blurMax,0,0), sct/2);
//blurShaderAnim = Vector(blurMin);
//blurShaderAnim.interpolateTo(Vector(blurMax,0,0), sct/2);
fhScale = 1;
}
@ -1142,9 +1142,9 @@ void Entity::update(float dt)
if (doUpdate && !dsq->game->isPaused())
{
if (getEntityType() == ET_ENEMY || getEntityType() == ET_NEUTRAL || getEntityType() == ET_PET)
if (!(getEntityType() == ET_AVATAR || getEntityType() == ET_INGREDIENT))
{
if (spiritFreeze && dsq->continuity.getWorldType() == WT_SPIRIT)
if (spiritFreeze && dsq->game->isWorldPaused())
{
// possible bug here because of return
return;
@ -1382,7 +1382,7 @@ bool Entity::updateCurrents(float dt)
// why?
{
//Path *p = dsq->game->getNearestPath(position, PATH_CURRENT);
if (dsq->continuity.getWorldType() != WT_SPIRIT)
if (!dsq->game->isWorldPaused())
{
for (Path *p = dsq->game->getFirstPathOfType(PATH_CURRENT); p; p = p->nextOfType)
{
@ -1419,7 +1419,7 @@ bool Entity::updateCurrents(float dt)
float useLen = len;
if (useLen < 500)
useLen = 500;
if (!(this->getEntityType() == ET_AVATAR && dsq->continuity.form == FORM_BEAST && dsq->game->avatar->bursting))
if (!(this->getEntityType() == ET_AVATAR && dsq->game->avatar->canSwimAgainstCurrents() && dsq->game->avatar->bursting))
{
doCollisionAvoidance(1, 4, 1, &vel2, useLen);
}
@ -1439,7 +1439,7 @@ bool Entity::updateCurrents(float dt)
}
}
}
if (this->getEntityType() == ET_AVATAR && dsq->continuity.form == FORM_BEAST)
if (this->getEntityType() == ET_AVATAR && dsq->game->avatar->canSwimAgainstCurrents())
{
int cap = 100;
if (!vel.isZero())
@ -1681,7 +1681,7 @@ void Entity::onUpdate(float dt)
break;
}
blurShaderAnim.update(dt);
//blurShaderAnim.update(dt);
}
@ -2832,23 +2832,18 @@ void Entity::render()
// HACK: need to multiply base + etc
skeletalSprite.setColorMult(this->color, this->alpha.x);
bool set=false;
/*bool set=false;
if (beautyFlip && blurShader.isLoaded() && flipScale.isInterpolating() && dsq->user.video.blur)
{
/*
std::ostringstream os;
os << "blurShaderAnim: " << blurShaderAnim.x;
debugLog(os.str());
*/
//swizzle
blurShader.setValue(color.x, color.y, color.z, blurShaderAnim.x);
blurShader.bind();
set = true;
}
}*/
Quad::render();
//if (beautyFlip && blurShader.isLoaded() && flipScale.isInterpolating())
if (set)
blurShader.unbind();
//if (set)
// blurShader.unbind();
renderBorder = false;
skeletalSprite.clearColorMult();
color = bcolor;
@ -3133,3 +3128,14 @@ void Entity::exertHairForce(const Vector &force, float dt)
}
}
bool Entity::isEntityInside()
{
FOR_ENTITIES(i)
{
Entity *e = *i;
if (e && e->life == 1 && e != this && e->ridingOnEntity != this && isCoordinateInside(e->position))
return true;
}
return false;
}

View file

@ -123,6 +123,7 @@ enum DamageType
DT_CRUSH = 1032,
DT_SPIKES = 1033,
DT_STEAM = 1034,
DT_WALLHURT = 1035,
DT_REALMAX
};
@ -436,6 +437,7 @@ public:
void setDieTimer(float v) { dieTimer = v; }
float getHealthPerc();
void setDeathScene(bool v);
bool isDeathScene() const { return deathScene; }
void generateCollisionMask(int ovrCollideRadius=0);
DamageData lastDamage;
bool checkSplash(const Vector &override=Vector(0,0,0));
@ -450,7 +452,7 @@ public:
//bool registerEntityDied;
bool clampToSurface(int tcheck=0, Vector usePos=Vector(0,0), TileVector hitTile=TileVector(0,0));
bool checkSurface(int tcheck, int state, float statet);
static Shader blurShader;
//static Shader blurShader;
std::string naijaReaction;
Vector lookAtPoint;
Vector getLookAtPoint();
@ -488,6 +490,8 @@ public:
void setHairHeadPosition(const Vector &pos);
void exertHairForce(const Vector &force, float dt);
bool isEntityInside();
protected:
bool calledEntityDied;
Path *waterBubble;
@ -514,7 +518,7 @@ protected:
int lance;
Bone *lanceBone;
void updateLance(float dt);
InterpolatedVector blurShaderAnim;
//InterpolatedVector blurShaderAnim;
int fhScale, fvScale;

View file

@ -394,7 +394,7 @@ void FoodSlot::refresh(bool effects)
{
std::ostringstream os;
if (i->amount > 1)
os << i->amount << "/" << MAX_INGREDIENT_AMOUNT;
os << i->amount << "/" << i->maxAmount;
label->setText(os.str());
setTexture("Ingredients/" + i->gfx);
renderQuad = true;
@ -455,12 +455,15 @@ void FoodSlot::eatMe()
}
if (!ingredient->effects.empty())
{
bool eaten = dsq->continuity.applyIngredientEffects(ingredient);
if(eaten)
{
ingredient->amount--;
dsq->continuity.applyIngredientEffects(ingredient);
dsq->continuity.removeEmptyIngredients();
dsq->game->refreshFoodSlots(true);
}
}
else
{
dsq->sound->playSfx("denied");
@ -533,7 +536,7 @@ void FoodSlot::onUpdate(float dt)
Vector wp = getWorldPosition();
if ((dsq->game->lips->getWorldPosition() - getWorldPosition()).isLength2DIn(32))
if ((dsq->game->lips->getWorldPosition() - wp).isLength2DIn(32))
{
dsq->menuSelectDelay = 0.5;
@ -548,7 +551,7 @@ void FoodSlot::onUpdate(float dt)
bool droppedIn = false;
for (int i = 0; i < foodHolders.size(); i++)
{
bool in = (foodHolders[i]->getWorldPosition() - getWorldPosition()).isLength2DIn(32);
bool in = (foodHolders[i]->getWorldPosition() - wp).isLength2DIn(32);
if (in)
{
droppedIn = true;
@ -587,11 +590,6 @@ void FoodSlot::onUpdate(float dt)
label->alpha = 1;
grabTime = 0;
if (dsq->inputMode == INPUT_JOYSTICK)
{
dsq->game->adjustFoodSlotCursor();
}
return;
}
else
@ -1233,6 +1231,10 @@ Game::Game() : StateObject()
loadEntityTypeList();
lastCollideMaskIndex = -1;
worldPaused = false;
cookingScript = 0;
}
@ -2430,8 +2432,7 @@ void Game::loadEntityTypeList()
std::string line;
if(!in)
{
core->messageBox(dsq->continuity.stringBank.get(2008), dsq->continuity.stringBank.get(2016));
exit(1);
exit_error(dsq->continuity.stringBank.get(2008).c_str());
}
while (std::getline(in, line))
{
@ -5211,7 +5212,7 @@ bool Game::loadScene(std::string scene)
}
if (i == allowedMaps.size())
{
exit(-1);
exit_error("Demo version refuses to load this map, sorry.");
}
#endif
@ -5717,7 +5718,7 @@ void Game::updateParticlePause()
{
core->particlesPaused = 2;
}
else if (dsq->continuity.getWorldType() == WT_SPIRIT)
else if (this->isWorldPaused())
{
core->particlesPaused = 1;
}
@ -5834,41 +5835,6 @@ float Game::getHalfTimer(float mod)
return halfTimer*mod;
}
void Game::adjustFoodSlotCursor()
{
// using visible slots now, don't need this atm
return;
/*
for (int i = 0; i < foodSlots.size(); i++)
{
if (foodSlots[i]->isCursorIn())
{
if (!foodSlots[i]->getIngredient() || foodSlots[i]->getIngredient()->amount <= 0)
{
foodSlots[i]->setFocus(false);
i--;
while (i >= 0)
{
if (foodSlots[i]->getIngredient() && foodSlots[i]->getIngredient()->amount > 0)
{
//cursor->position = foodSlots[i]->getWorldPosition();
foodSlots[i]->setFocus(true);
break;
}
i--;
}
if (i <= -1)
{
menu[5]->setFocus(true);
//cursor->position = menu[5]->getWorldPosition();
}
}
break;
}
}
*/
}
void Game::action(int id, int state)
{
for (int i = 0; i < paths.size(); i++)
@ -5992,7 +5958,6 @@ void Game::action(int id, int state)
if (foodSlots[i]->isCursorIn() && foodSlots[i]->getIngredient())
{
foodSlots[i]->moveRight();
adjustFoodSlotCursor();
break;
}
}
@ -6029,7 +5994,6 @@ void Game::action(int id, int state)
if (ingrIndex >= 0)
{
foodSlots[ingrIndex]->discard();
adjustFoodSlotCursor();
}
}
}
@ -6707,6 +6671,14 @@ void Game::applyState()
musicToPlay = overrideMusic;
}
if(cookingScript)
dsq->scriptInterface.closeScript(cookingScript);
if (dsq->mod.isActive())
cookingScript = dsq->scriptInterface.openScript(dsq->mod.getPath() + "scripts/cooking.lua", true);
else
cookingScript = dsq->scriptInterface.openScript("scripts/global/cooking.lua", true);
//INFO: this used to be here to start fading out the music
// before the level had begun
/*
@ -7242,7 +7214,22 @@ void Game::onCook()
if (r)
data = dsq->continuity.getIngredientDataByName(r->result);
else
else if(cookingScript)
{
const char *p1 = cookList[0]->name.c_str();
const char *p2 = cookList[1]->name.c_str();
const char *p3 = cookList.size() >= 3 ? cookList[2]->name.c_str() : "";
std::string ingname;
if(cookingScript->call("cookFailure", p1, p2, p3, &ingname))
{
if(ingname.length())
data = dsq->continuity.getIngredientDataByName(ingname);
if(!data)
goto endcook;
}
}
if(!data)
{
dsq->sound->playSfx("Denied");
data = dsq->continuity.getIngredientDataByName("SeaLoaf");
@ -7422,6 +7409,8 @@ void Game::onCook()
}
refreshFoodSlots(true);
endcook:
AquariaGuiElement::canDirMoveGlobal = true;
isCooking = false;
@ -8356,7 +8345,7 @@ void Game::registerSporeDrop(const Vector &pos, int t)
bool Game::isEntityCollideWithShot(Entity *e, Shot *shot)
{
if (!shot->isHitEnts())
if (!shot->isHitEnts() || shot->firer == e)
{
return false;
}
@ -8366,8 +8355,6 @@ bool Game::isEntityCollideWithShot(Entity *e, Shot *shot)
return false;
}
if (e->getEntityType() == ET_ENEMY)
{
if (shot->firer != e)
{
if (shot->getDamageType() == DT_AVATAR_BITE)
{
@ -8382,11 +8369,6 @@ bool Game::isEntityCollideWithShot(Entity *e, Shot *shot)
return true;
}
}
else
{
return false;
}
}
else if (e->getEntityType() == ET_AVATAR)
{
// this used to be stuff != ET_AVATAR.. but what else would do that
@ -8745,7 +8727,6 @@ void Game::refreshFoodSlots(bool effects)
{
foodSlots[i]->refresh(effects);
}
adjustFoodSlotCursor();
}
void Game::refreshTreasureSlots()
@ -9977,7 +9958,7 @@ void Game::update(float dt)
if (avatar)
{
tintColor.update(dt);
/*tintColor.update(dt);
if (core->afterEffectManager)
{
if (tintColor.isInterpolating())
@ -9986,7 +9967,7 @@ void Game::update(float dt)
core->afterEffectManager->setActiveShader(AS_NONE);
core->afterEffectManager->glowShader.setValue(tintColor.x, tintColor.y, tintColor.z, 1);
}
}*/
if (avatar->isRolling())
particleManager->addInfluence(ParticleInfluence(avatar->position, 300, 800, true));
@ -10724,11 +10705,6 @@ void Game::removeState()
elementUpdateList.clear();
if (core->afterEffectManager)
{
//core->afterEffectManager->blurShader.setMode(0);
core->afterEffectManager->setActiveShader(AS_NONE);
}
dsq->setCursor(CURSOR_NORMAL);
dsq->darkLayer.toggle(0);
dsq->shakeCamera(0,0);

View file

@ -714,6 +714,8 @@ public:
Ingredient *getNearestIngredient(const Vector &pos, int radius);
Entity *getNearestEntity(const Vector &pos, int radius, Entity *ignore = 0, EntityType et=ET_NOTYPE, DamageType dt=DT_NONE, int lrStart=-1, int lrEnd=-1);
Script *cookingScript;
void spawnManaBall(Vector pos, float a);
bool updateMusic();
std::string overrideMusic;
@ -892,7 +894,8 @@ public:
std::string getNoteName(int n, const std::string &pre="");
void selectEntityFromGroups();
InterpolatedVector cameraInterp, tintColor;
InterpolatedVector cameraInterp;
//InterpolatedVector tintColor;
float getWaterLevel();
void setMusicToPlay(const std::string &musicToPlay);
Vector lastCollidePosition;
@ -1001,6 +1004,9 @@ public:
void toggleHelpScreen(bool on, const std::string &label="");
void onToggleHelpScreen();
void setWorldPaused(bool b) { worldPaused = b; }
bool isWorldPaused() const { return worldPaused; }
protected:
void onHelpUp();
@ -1158,6 +1164,7 @@ protected:
std::vector<AquariaMenuItem*> menu;
Quad *menuBg, *menuBg2;
bool paused;
bool worldPaused;
Vector getClosestPointOnTriangle(Vector a, Vector b, Vector c, Vector p);
Vector getClosestPointOnLine(Vector a, Vector b, Vector p);

View file

@ -27,8 +27,7 @@ void GameplayVariables::load()
InStream inFile("data/variables.txt");
if(!inFile)
{
core->messageBox(dsq->continuity.stringBank.get(2008), dsq->continuity.stringBank.get(2017));
exit(1);
exit_error(dsq->continuity.stringBank.get(2017));
}
std::string s;
inFile >> s >> maxSlowSwimSpeed;

View file

@ -130,7 +130,7 @@ HairNode *Hair::getHairNode(int idx)
void Hair::onRender()
{
#ifdef BBGE_BUILD_OPENGL
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
glBegin(GL_QUAD_STRIP);
float texBits = 1.0f / (hairNodes.size()-1);
@ -192,7 +192,7 @@ void Hair::onRender()
}
*/
glEnable(GL_CULL_FACE);
//glEnable(GL_CULL_FACE);
#endif
}

View file

@ -22,8 +22,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "Avatar.h"
IngredientData::IngredientData(const std::string &name, const std::string &gfx, IngredientType type)
: name(name), gfx(gfx), amount(0), held(0), type(type), marked(0), sorted(false)
: name(name), gfx(gfx), amount(0), maxAmount(MAX_INGREDIENT_AMOUNT), held(0), type(type), marked(0), sorted(false)
, displayName(dsq->continuity.getIngredientDisplayName(name))
, rotKind(!(type == IT_OIL && type == IT_EGG))
{
}
@ -83,15 +84,7 @@ void Ingredient::destroy()
bool Ingredient::isRotKind()
{
if (data)
{
if (data->type == IT_OIL || data->type == IT_EGG)
{
return false;
}
return true;
}
return false;
return data && data->rotKind;
}
IngredientData *Ingredient::getIngredientData()
@ -109,7 +102,7 @@ void Ingredient::eat(Entity *e)
void Ingredient::onUpdate(float dt)
{
if (dsq->game->isPaused()) return;
if (dsq->continuity.getWorldType() == WT_SPIRIT) return;
if (dsq->game->isWorldPaused()) return;
Vector lastPosition = position;
Entity::onUpdate(dt);

View file

@ -258,11 +258,18 @@ void MiniMapRender::onUpdate(float dt)
if (dsq->darkLayer.isUsed() && dsq->game->avatar)
{
if (dsq->continuity.form != FORM_SUN && dsq->game->avatar->isInDarkness())
const SeeMapMode mapmode = dsq->game->avatar->getSeeMapMode();
if(mapmode == SEE_MAP_ALWAYS)
radarHide = false;
else if(mapmode == SEE_MAP_NEVER)
radarHide = true;
else if (dsq->continuity.form != FORM_SUN && dsq->game->avatar->isInDarkness())
{
radarHide = true;
}
else
if(!radarHide)
{
for (Path *p = dsq->game->getFirstPathOfType(PATH_RADARHIDE); p; p = p->nextOfType)
{
@ -273,6 +280,7 @@ void MiniMapRender::onUpdate(float dt)
}
}
}
float t = dt*2;
if (radarHide)
{

View file

@ -39,6 +39,11 @@ Mod::Mod()
shuttingDown = false;
}
Mod::~Mod()
{
modcache.clean();
}
/*
queue for actual stop and recache
which happens in game::applystate
@ -182,6 +187,23 @@ void Mod::recache()
core->resetTimer();
}
if(active)
{
modcache.setBaseDir(dsq->secondaryTexturePath);
std::string fname = path;
if(fname[fname.length() - 1] != '/')
fname += '/';
fname += "precache.txt";
fname = localisePath(fname, dsq->mod.getPath());
fname = core->adjustFilenameCase(fname);
if (exists(fname))
modcache.precacheList(fname);
}
else
{
modcache.clean();
}
}
void Mod::start()
@ -284,6 +306,7 @@ void Mod::stop()
debugMenu = false;
shuttingDown = false;
dsq->scriptInterface.reset();
dsq->game->setWorldPaused(false);
}
void Mod::update(float dt)

View file

@ -53,12 +53,7 @@ Path::Path()
spawnEnemyNumber = 0;
spawnEnemyDistance = 0;
warpType = 0;
/*
rect.x1 = -10;
rect.x2 = 20;
rect.y1 = -256;
rect.y2 = 256;
*/
spiritFreeze = true;
}
void Path::clampPosition(Vector *pos, int radius)
@ -484,7 +479,7 @@ void Path::init()
void Path::update(float dt)
{
if (!dsq->game->isPaused() && dsq->continuity.getWorldType() == WT_NORMAL)
if (!dsq->game->isPaused() && !(spiritFreeze && dsq->game->isWorldPaused()))
{
if (addEmitter && emitter)
{
@ -523,7 +518,7 @@ void Path::update(float dt)
{
spawnedEntity = 0;
}
if (pathType == PATH_CURRENT && dsq->continuity.getWorldType() == WT_NORMAL)
if (pathType == PATH_CURRENT && !dsq->game->isWorldPaused())
{
animOffset -= currentMod*(dt/830);
/*
@ -559,7 +554,7 @@ void Path::update(float dt)
}
}
if (pathType == PATH_STEAM && dsq->continuity.getWorldType() == WT_NORMAL && effectOn)
if (pathType == PATH_STEAM && !dsq->game->isWorldPaused() && effectOn)
{
animOffset -= 1000*0.00002f;

View file

@ -143,6 +143,7 @@ public:
std::string gem;
bool effectOn;
bool spiritFreeze;
PathShape pathShape;

View file

@ -3578,10 +3578,10 @@ void SceneEditor::update(float dt)
(dsq->getGameCursorPosition().y - cursorOffset.y)*factor);
//editingElement->scale=oldScale + add;
Vector sz = oldScale + add;
if (sz.x < 64)
sz.x = 64;
if (sz.y < 64)
sz.y = 64;
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;

View file

@ -76,6 +76,7 @@ static const char * const interfaceFunctions[] = {
"activate",
"animationKey",
"castSong",
"cookFailure",
"damage",
"deathNotify",
"dieEaten",
@ -84,6 +85,7 @@ static const char * const interfaceFunctions[] = {
"entityDied",
"exitState",
"exitTimer",
"getIngredientString",
"hitEntity",
"hitSurface",
"init",
@ -98,6 +100,7 @@ static const char * const interfaceFunctions[] = {
"songNoteDone",
"sporesDropped",
"update",
"useIngredient",
"useTreasure",
NULL
};
@ -361,7 +364,7 @@ static void scriptError(lua_State *L, const std::string& msg)
// - The C++ standard allows offsetof() only on POD-types. Oh well, it probably works anyways.
// If it does not compile for some reason, comment it out, hope for the best, and go ahead.
#if !(defined(__GNUC__) && __GNUC__ <= 2)
void compile_time_assertions()
static void compile_time_assertions()
{
#define oo(cls) offsetof(cls, _objtype)
compile_assert(oo(Path) == oo(RenderObject));
@ -377,6 +380,7 @@ void compile_time_assertions()
compile_assert(oo(Path) == oo(Quad));
compile_assert(oo(Path) == oo(Avatar));
compile_assert(oo(Path) == oo(BaseText));
compile_assert(oo(Path) == oo(PauseQuad));
#undef oo
}
#endif
@ -457,6 +461,12 @@ std::string getString(lua_State *L, int slot = 1)
return sr;
}
static inline
const char *getCString(lua_State *L, int slot = 1)
{
return lua_isstring(L, slot) ? lua_tostring(L, slot) : NULL;
}
static inline
Shot *getShot(lua_State *L, int slot = 1)
{
@ -578,6 +588,16 @@ BaseText *getText(lua_State *L, int slot = 1)
return q;
}
static inline
Shader *getShader(lua_State *L, int slot = 1)
{
Shader *q = (Shader*)lua_touserdata(L, slot);
ENSURE_TYPE(q, SCO_SHADER);
if (!q)
scriptDebug(L, "Invalid Shader");
return q;
}
static SkeletalSprite *getSkeletalSprite(Entity *e)
{
return e ? &e->skeletalSprite : NULL;
@ -693,8 +713,8 @@ luaFunc(indexWarnInstance)
luaFunc(panicHandler)
{
errorLog(luaFormatStackInfo(L) + ": Lua PANIC: " + getString(L, -1));
exit(1);
std::string err = luaFormatStackInfo(L) + ": Lua PANIC: " + getString(L, -1);
exit_error(err);
}
static bool findFile_helper(const char *rawname, std::string &fname)
@ -847,6 +867,12 @@ luaFunc(obj_alphaMod)
luaReturnNil()
}
luaFunc(obj_getAlphaMod)
{
RenderObject *r = robj(L);
luaReturnNum(r ? r->alphaMod : 0.0f);
}
luaFunc(obj_getAlpha)
{
RenderObject *r = robj(L);
@ -865,6 +891,16 @@ luaFunc(obj_color)
luaReturnNil();
}
luaFunc(obj_getColor)
{
RenderObject *r = robj(L);
Vector c;
if(r)
c = r->color;
luaReturnVec3(c.x, c.y, c.z);
}
luaFunc(obj_rotate)
{
RenderObject *r = robj(L);
@ -1517,7 +1553,9 @@ luaFunc(quad_setSegs)
RO_FUNC(getter, prefix, alpha ) \
RO_FUNC(getter, prefix, alphaMod ) \
RO_FUNC(getter, prefix, getAlpha ) \
RO_FUNC(getter, prefix, getAlphaMod ) \
RO_FUNC(getter, prefix, color ) \
RO_FUNC(getter, prefix, getColor ) \
RO_FUNC(getter, prefix, rotate ) \
RO_FUNC(getter, prefix, rotateOffset ) \
RO_FUNC(getter, prefix, getRotation ) \
@ -1579,6 +1617,7 @@ luaFunc(quad_setSegs)
RO_FUNC(getter, prefix, disableMotionBlur ) \
RO_FUNC(getter, prefix, collideCircleVsLine) \
RO_FUNC(getter, prefix, collideCircleVsLineAngle) \
RO_FUNC(getter, prefix, getVectorToObj ) \
MK_ALIAS(prefix, fh, flipHorizontal ) \
MK_ALIAS(prefix, fv, flipVertical )
@ -2112,18 +2151,22 @@ luaFunc(entity_setRidingData)
luaFunc(entity_setBoneLock)
{
Entity *e = entity(L);
Entity *e2 = entity(L, 2);
Bone *b = 0;
if (lua_isuserdata(L, 3))
b = bone(L, 3);
bool ret = false;
if (e)
{
BoneLock bl;
if (lua_isuserdata(L, 2))
{
Entity *e2 = entity(L, 2);
Bone *b = 0;
if (lua_isuserdata(L, 3))
b = bone(L, 3);
bl.entity = e2;
bl.bone = b;
bl.on = true;
bl.collisionMaskIndex = dsq->game->lastCollideMaskIndex;
}
ret = e->setBoneLock(bl);
}
luaReturnBool(ret);
@ -2347,6 +2390,25 @@ luaFunc(getWorldType)
luaReturnNum((int)dsq->continuity.getWorldType());
}
luaFunc(setWorldType)
{
WorldType wt = (WorldType)lua_tointeger(L, 1);
bool trans = getBool(L, 2);
dsq->continuity.applyWorldEffects(wt, trans, 1); // last arg is not used
luaReturnNil();
}
luaFunc(isWorldPaused)
{
luaReturnBool(dsq->game->isWorldPaused());
}
luaFunc(setWorldPaused)
{
dsq->game->setWorldPaused(getBool(L, 1));
luaReturnNil();
}
luaFunc(getNearestNodeByType)
{
int x = lua_tonumber(L, 1);
@ -2542,6 +2604,14 @@ luaFunc(entity_setSpiritFreeze)
luaReturnNil();
}
luaFunc(node_setSpiritFreeze)
{
Path *e = path(L);
if (e)
e->spiritFreeze = getBool(L,2);
luaReturnNil();
}
luaFunc(entity_setFillGrid)
{
Entity *e = entity(L);
@ -2553,6 +2623,12 @@ luaFunc(entity_setFillGrid)
luaReturnNil();
}
luaFunc(entity_isFillGrid)
{
Entity *e = entity(L);
luaReturnBool(e ? e->fillGridFromQuad : false);
}
luaFunc(entity_getAimVector)
{
Entity *e = entity(L);
@ -2679,6 +2755,69 @@ luaFunc(avatar_setCanDie)
luaReturnNil();
}
// not naming this avatar_* because it rather belongs into the UI category...
luaFunc(setCanActivate)
{
dsq->game->avatar->setCanActivateStuff(getBool(L, 1));
luaReturnNil();
}
luaFunc(setSeeMapMode)
{
dsq->game->avatar->setSeeMapMode((SeeMapMode)lua_tointeger(L, 1));
luaReturnNil();
}
luaFunc(avatar_setCanBurst)
{
dsq->game->avatar->setCanBurst(getBool(L, 1));
luaReturnNil();
}
luaFunc(avatar_canBurst)
{
luaReturnBool(dsq->game->avatar->canBurst());
}
luaFunc(avatar_setCanLockToWall)
{
dsq->game->avatar->setCanLockToWall(getBool(L, 1));
luaReturnNil();
}
luaFunc(avatar_canLockToWall)
{
luaReturnBool(dsq->game->avatar->canLockToWall());
}
luaFunc(avatar_setCanSwimAgainstCurrents)
{
dsq->game->avatar->setCanSwimAgainstCurrents(getBool(L, 1));
luaReturnNil();
}
luaFunc(avatar_canSwimAgainstCurrents)
{
luaReturnBool(dsq->game->avatar->canSwimAgainstCurrents());
}
luaFunc(avatar_setCanCollideWithShots)
{
dsq->game->avatar->setCollideWithShots(getBool(L, 1));
luaReturnNil();
}
luaFunc(avatar_canCollideWithShots)
{
luaReturnBool(dsq->game->avatar->canCollideWithShots());
}
luaFunc(avatar_setCollisionAvoidanceData)
{
dsq->game->avatar->setCollisionAvoidanceData(lua_tointeger(L, 1), lua_tonumber(L, 2));
luaReturnNil();
}
luaFunc(avatar_toggleCape)
{
dsq->game->avatar->toggleCape(getBool(L,1));
@ -2693,6 +2832,11 @@ luaFunc(avatar_setBlockSinging)
luaReturnNil();
}
luaFunc(avatar_isBlockSinging)
{
luaReturnBool(dsq->game->avatar->isBlockSinging());
}
luaFunc(avatar_fallOffWall)
{
dsq->game->avatar->fallOffWall();
@ -2726,6 +2870,16 @@ luaFunc(avatar_isShieldActive)
luaReturnBool(v);
}
luaFunc(avatar_setShieldActive)
{
bool on = getBool(L, 1);
if (on)
dsq->game->avatar->activateAura(AURA_SHIELD);
else
dsq->game->avatar->stopAura();
luaReturnNil();
}
luaFunc(avatar_getStillTimer)
{
luaReturnNum(dsq->game->avatar->stillTimer.getValue());
@ -2744,6 +2898,28 @@ luaFunc(avatar_getSpellCharge)
luaReturnNum(dsq->game->avatar->state.spellCharge);
}
luaFunc(avatar_setSpeedMult)
{
dsq->continuity.setSpeedMultiplier(lua_tonumber(L, 1), lua_tonumber(L, 2));
luaReturnNil();
}
luaFunc(avatar_setSpeedMult2)
{
dsq->continuity.speedMult2 = lua_tonumber(L, 1);
luaReturnNil();
}
luaFunc(avatar_getSpeedMult)
{
luaReturnNum(dsq->continuity.speedMult);
}
luaFunc(avatar_getSpeedMult2)
{
luaReturnNum(dsq->continuity.speedMult2);
}
luaFunc(jumpState)
{
dsq->enqueueJumpState(getString(L, 1), getBool(L, 2));
@ -2846,11 +3022,6 @@ luaFunc(entity_followPath)
luaReturnNil();
}
luaFunc(getIngredientGfx)
{
luaReturnStr(dsq->continuity.getIngredientGfx(getString(L, 1)).c_str());
}
luaFunc(spawnIngredient)
{
int times = lua_tonumber(L, 4);
@ -2887,6 +3058,27 @@ luaFunc(spawnParticleEffect)
luaReturnPtr(pe);
}
luaFunc(setNumSuckPositions)
{
particleManager->setNumSuckPositions(lua_tointeger(L, 1));
luaReturnNil();
}
luaFunc(setSuckPosition)
{
particleManager->setSuckPosition(lua_tointeger(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
luaReturnNil();
}
luaFunc(getSuckPosition)
{
Vector *v = particleManager->getSuckPosition(lua_tointeger(L, 1));
if(v)
luaReturnVec2(v->x, v->y);
luaReturnVec2(0.0f, 0.0f);
}
luaFunc(bone_showFrame)
{
Bone *b = bone(L);
@ -3038,6 +3230,11 @@ luaFunc(entity_checkSplash)
luaReturnBool(ret);
}
luaFunc(entity_isInCurrent)
{
Entity *e = entity(L);
luaReturnBool(e ? e->isInCurrent() : false);
}
luaFunc(entity_isUnderWater)
{
@ -3612,6 +3809,16 @@ luaFunc(beam_setDamage)
luaReturnNil();
}
luaFunc(beam_setDamageType)
{
Beam *b = beam(L);
if (b)
{
b->damageData.damageType = (DamageType)lua_tointeger(L, 2);
}
luaReturnNil();
}
luaFunc(beam_setBeamWidth)
{
Beam *b = beam(L);
@ -3741,6 +3948,12 @@ luaFunc(setSceneColor)
luaReturnNil();
}
luaFunc(getSceneColor)
{
const Vector& c = dsq->game->sceneColor3;
luaReturnVec3(c.x, c.y, c.z);
}
luaFunc(setCameraLerpDelay)
{
dsq->game->cameraLerpDelay = lua_tonumber(L, 1);
@ -3806,6 +4019,8 @@ luaFunc(entity_damage)
d.attacker = lua_isuserdata(L, 2) ? entity(L, 2) : NULL;
d.damage = lua_tonumber(L, 3);
d.damageType = (DamageType)lua_tointeger(L, 4);
d.effectTime = lua_tonumber(L, 5);
d.useTimer = !getBool(L, 6);
didDamage = e->damage(d);
}
luaReturnBool(didDamage);
@ -4577,6 +4792,18 @@ luaFunc(entity_getDistanceToTarget)
luaReturnNum(dist);
}
luaFunc(entity_getDistanceToPoint)
{
Entity *e = entity(L);
float dist = 0;
if (e)
{
Vector p(lua_tonumber(L, 2), lua_tonumber(L, 3));
dist = (p - e->position).getLength2D();
}
luaReturnNum(dist);
}
luaFunc(entity_watchEntity)
{
Entity *e = entity(L);
@ -4731,6 +4958,15 @@ luaFunc(createQuad)
luaReturnPtr(q);
}
luaFunc(quad_setPauseLevel)
{
Quad *q = getQuad(L);
ENSURE_TYPE(q, SCO_PAUSEQUAD);
if (q)
((PauseQuad*)q)->pauseLevel = lua_tointeger(L, 2);
luaReturnNil();
}
luaFunc(setupEntity)
{
ScriptedEntity *se = scriptedEntity(L);
@ -5045,6 +5281,12 @@ luaFunc(entity_setMaxSpeedLerp)
luaReturnNil();
}
luaFunc(entity_getMaxSpeedLerp)
{
Entity *e = entity(L);
luaReturnNum(e ? e->maxSpeedLerp.x : 0.0f);
}
// note: this is a weaker setState than perform
// this is so that things can override it
// for example getting PUSH-ed (Force) or FROZEN (bubbled)
@ -5217,6 +5459,12 @@ luaFunc(entity_setDeathScene)
luaReturnNil();
}
luaFunc(entity_isDeathScene)
{
Entity *e = entity(L);
luaReturnBool(e ? e->isDeathScene() : false);
}
luaFunc(entity_setCurrentTarget)
{
Entity *e = entity(L);
@ -5388,6 +5636,12 @@ luaFunc(entity_getRandomTargetPoint)
luaReturnNum(idx);
}
luaFunc(entity_getNumTargetPoints)
{
Entity *e = entity(L);
luaReturnInt(e ? e->getNumTargetPoints() : 0);
}
luaFunc(playVisualEffect)
{
Entity *target = NULL;
@ -6155,6 +6409,12 @@ luaFunc(entity_getDistanceToEntity)
luaReturnNum(d);
}
luaFunc(entity_isEntityInside)
{
Entity *e = entity(L);
luaReturnBool(e ? e->isEntityInside() : false);
}
// entity_istargetInRange
luaFunc(entity_isTargetInRange)
{
@ -6499,6 +6759,13 @@ luaFunc(ing_hasIET)
luaReturnBool(has);
}
luaFunc(ing_getIngredientName)
{
Ingredient *i = getIng(L, 1);
IngredientData *data = i ? i->getIngredientData() : 0;
luaReturnStr(data ? data->name.c_str() : "");
}
luaFunc(entity_getNearestEntity)
{
Entity *me = entity(L);
@ -6559,6 +6826,20 @@ luaFunc(entity_getNearestEntity)
luaReturnPtr(closest);
}
luaFunc(getNearestEntity)
{
Vector p(lua_tonumber(L, 1), lua_tonumber(L, 2));
int radius = lua_tointeger(L, 3);
Entity *ignore = lua_isuserdata(L, 4) ? entity(L, 4) : NULL;
EntityType et = lua_isnumber(L, 5) ? (EntityType)lua_tointeger(L, 5) : ET_NOTYPE;
DamageType dt = lua_isnumber(L, 6) ? (DamageType)lua_tointeger(L, 6) : DT_NONE;
int lrStart = lua_isnumber(L, 7) ? lua_tointeger(L, 7) : -1;
int lrEnd = lua_isnumber(L, 8) ? lua_tointeger(L, 8) : -1;
Entity *target = dsq->game->getNearestEntity(p, radius, ignore, ET_ENEMY, dt, lrStart, lrEnd);
luaReturnPtr(target);
}
luaFunc(findWall)
{
int x = lua_tonumber(L, 1);
@ -6755,7 +7036,7 @@ luaFunc(entity_getHair)
luaFunc(entity_clearHair)
{
Entity *e = entity(L);
if (e)
if (e && e->hair)
{
e->hair->safeKill();
e->hair = 0;
@ -7062,21 +7343,21 @@ luaFunc(getMouseWorldPos)
luaFunc(fade)
{
dsq->overlay->color = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5));
dsq->overlay->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6));
dsq->overlay->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2));
luaReturnNil();
}
luaFunc(fade2)
{
dsq->overlay2->color = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5));
dsq->overlay2->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6));
dsq->overlay2->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2));
luaReturnNil();
}
luaFunc(fade3)
{
dsq->overlay3->color = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5));
dsq->overlay3->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6));
dsq->overlay3->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2));
luaReturnNil();
}
@ -7461,6 +7742,82 @@ luaFunc(getScreenSize)
luaReturnVec2(core->width, core->height);
}
luaFunc(inv_isFull)
{
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
bool full = false;
if(data)
full = dsq->continuity.isIngredientFull(data);
luaReturnBool(full);
}
luaFunc(inv_getMaxAmount)
{
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
luaReturnInt(data ? data->maxAmount : 0);
}
luaFunc(inv_getAmount)
{
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
luaReturnInt(data ? data->amount : 0);
}
luaFunc(inv_add)
{
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
if(data)
dsq->continuity.pickupIngredient(data, lua_tointeger(L, 2), false, false);
luaReturnNil();
}
luaFunc(inv_getGfx)
{
luaReturnStr(dsq->continuity.getIngredientGfx(getString(L, 1)).c_str());
}
luaFunc(inv_remove)
{
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
if(data && data->amount > 0)
{
data->amount--;
dsq->game->dropIngrNames.push_back(data->name);
dsq->continuity.removeEmptyIngredients();
if(dsq->game->isInGameMenu())
dsq->game->refreshFoodSlots(true);
}
luaReturnNil();
}
luaFunc(inv_getType)
{
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
luaReturnInt(data ? data->type : 0);
}
luaFunc(inv_getDisplayName)
{
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
luaReturnStr(data ? data->displayName.c_str() : "");
}
luaFunc(inv_pickupEffect)
{
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
if(data)
dsq->game->pickupIngredientEffects(data);
luaReturnNil();
}
luaFunc(learnRecipe)
{
std::string name = getString(L, 1);
bool show = getBool(L, 2);
dsq->continuity.learnRecipe(name, show);
luaReturnNil();
}
luaFunc(createDebugText)
{
DebugFont *txt = new DebugFont(lua_tointeger(L, 2), getString(L, 1));
@ -7504,6 +7861,81 @@ luaFunc(text_setWidth)
luaReturnNil();
}
luaFunc(loadShader)
{
int handle = 0;
const char *vertRaw = getCString(L, 1);
const char *fragRaw = getCString(L, 2);
std::string vert, frag;
if(vertRaw)
findFile_helper(vertRaw, vert);
if(fragRaw)
findFile_helper(fragRaw, frag);
if(core->afterEffectManager)
handle = core->afterEffectManager->loadShaderFile(vert.c_str(), frag.c_str());
luaReturnInt(handle);
}
luaFunc(createShader)
{
int handle = 0;
if(core->afterEffectManager)
handle = core->afterEffectManager->loadShaderSrc(getCString(L, 1), getCString(L, 2));
luaReturnInt(handle);
}
luaFunc(shader_setAsAfterEffect)
{
int handle = lua_tointeger(L, 1);
int pos = lua_tointeger(L, 2);
bool done = false;
if(core->afterEffectManager)
done = core->afterEffectManager->setShaderPipelinePos(handle, pos);
luaReturnBool(done);
}
luaFunc(shader_setNumAfterEffects)
{
if(core->afterEffectManager)
core->afterEffectManager->setShaderPipelineSize(lua_tointeger(L, 1));
luaReturnNil();
}
luaFunc(shader_setInt)
{
if(core->afterEffectManager)
{
Shader *sh = core->afterEffectManager->getShaderPtr(lua_tointeger(L, 1));
const char *name = getCString(L, 2);
if(sh && name)
sh->setInt(name, lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5), lua_tointeger(L, 6));
}
luaReturnNil();
}
luaFunc(shader_setFloat)
{
if(core->afterEffectManager)
{
Shader *sh = core->afterEffectManager->getShaderPtr(lua_tointeger(L, 1));
const char *name = getCString(L, 2);
if(sh && name)
sh->setFloat(name, lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6));
}
luaReturnNil();
}
luaFunc(shader_delete)
{
if(core->afterEffectManager)
core->afterEffectManager->unloadShader(lua_tointeger(L, 1));
luaReturnNil();
}
//--------------------------------------------------------------------------------------------
@ -7541,11 +7973,15 @@ static const struct {
luaRegister(getNoteName),
luaRegister(getWorldType),
luaRegister(setWorldType),
luaRegister(setWorldPaused),
luaRegister(isWorldPaused),
luaRegister(getWaterLevel),
luaRegister(setWaterLevel),
luaRegister(createQuad),
luaRegister(quad_setPauseLevel),
luaRegister(setupEntity),
luaRegister(setActivePet),
@ -7554,6 +7990,7 @@ static const struct {
luaRegister(reconstructEntityGrid),
luaRegister(ing_hasIET),
luaRegister(ing_getIngredientName),
luaRegister(esetv),
luaRegister(esetvf),
@ -7570,6 +8007,7 @@ static const struct {
luaRegister(entity_setBoneLock),
luaRegister(entity_setIngredient),
luaRegister(entity_setDeathScene),
luaRegister(entity_isDeathScene),
luaRegister(entity_setBeautyFlip),
luaRegister(entity_setInvincible),
@ -7594,6 +8032,7 @@ static const struct {
luaRegister(entity_setEatType),
luaRegister(entity_setSpiritFreeze),
luaRegister(node_setSpiritFreeze),
luaRegister(entity_setCanLeaveWater),
@ -7614,9 +8053,20 @@ static const struct {
luaRegister(avatar_setCanDie),
luaRegister(setCanActivate),
luaRegister(setSeeMapMode),
luaRegister(avatar_toggleCape),
luaRegister(avatar_setPullTarget),
luaRegister(avatar_setCanLockToWall),
luaRegister(avatar_canLockToWall),
luaRegister(avatar_setCanBurst),
luaRegister(avatar_canBurst),
luaRegister(avatar_setCanSwimAgainstCurrents),
luaRegister(avatar_canSwimAgainstCurrents),
luaRegister(avatar_setCanCollideWithShots),
luaRegister(avatar_canCollideWithShots),
luaRegister(avatar_setCollisionAvoidanceData),
luaRegister(avatar_clampPosition),
luaRegister(avatar_updatePosition),
@ -7649,9 +8099,11 @@ static const struct {
luaRegister(entity_isUnderWater),
luaRegister(entity_checkSplash),
luaRegister(entity_isInCurrent),
luaRegister(entity_getRandomTargetPoint),
luaRegister(entity_getTargetPoint),
luaRegister(entity_getNumTargetPoints),
luaRegister(entity_setTargetRange),
@ -7676,6 +8128,7 @@ static const struct {
luaRegister(beam_setDamage),
luaRegister(beam_setBeamWidth),
luaRegister(beam_setFirer),
luaRegister(beam_setDamageType),
luaRegister(getStringBank),
@ -7721,6 +8174,7 @@ static const struct {
luaRegister(entity_getVectorToEntity),
luaRegister(entity_getDistanceToTarget),
luaRegister(entity_getDistanceToPoint),
luaRegister(entity_move),
luaRegister(entity_getID),
@ -7818,6 +8272,7 @@ static const struct {
luaRegister(entity_isTargetInRange),
luaRegister(entity_getDistanceToEntity),
luaRegister(entity_isEntityInside),
luaRegister(entity_isInvincible),
@ -7834,6 +8289,7 @@ static const struct {
luaRegister(entity_setMaxSpeed),
luaRegister(entity_getMaxSpeed),
luaRegister(entity_setMaxSpeedLerp),
luaRegister(entity_getMaxSpeedLerp),
luaRegister(entity_setState),
luaRegister(entity_getState),
luaRegister(entity_getEnqueuedState),
@ -7857,8 +8313,6 @@ static const struct {
luaRegister(registerSporeDrop),
luaRegister(getIngredientGfx),
luaRegister(spawnIngredient),
luaRegister(spawnAllIngredients),
luaRegister(spawnParticleEffect),
@ -7869,6 +8323,9 @@ static const struct {
luaRegister(resetTimer),
luaRegister(addInfluence),
luaRegister(setSuckPosition),
luaRegister(setSuckPosition),
luaRegister(setNumSuckPositions),
luaRegister(setupBasicEntity),
luaRegister(playMusic),
luaRegister(playMusicStraight),
@ -8024,10 +8481,17 @@ static const struct {
luaRegister(avatar_isRolling),
luaRegister(avatar_isOnWall),
luaRegister(avatar_isShieldActive),
luaRegister(avatar_setShieldActive),
luaRegister(avatar_getRollDirection),
luaRegister(avatar_fallOffWall),
luaRegister(avatar_setBlockSinging),
luaRegister(avatar_isBlockSinging),
luaRegister(avatar_setSpeedMult),
luaRegister(avatar_setSpeedMult2),
luaRegister(avatar_getSpeedMult),
luaRegister(avatar_getSpeedMult2),
luaRegister(avatar_toggleMovement),
@ -8223,7 +8687,7 @@ static const struct {
luaRegister(setSceneColor),
luaRegister(getSceneColor),
luaRegister(entity_watchEntity),
@ -8251,6 +8715,7 @@ static const struct {
luaRegister(entity_setTexture),
luaRegister(entity_setFillGrid),
luaRegister(entity_isFillGrid),
luaRegister(entity_push),
@ -8315,6 +8780,7 @@ static const struct {
luaRegister(entity_getNearestEntity),
luaRegister(entity_getNearestBoneToPosition),
luaRegister(getNearestEntity),
luaRegister(entity_getNearestNode),
luaRegister(entity_setPoison),
@ -8344,12 +8810,31 @@ static const struct {
luaRegister(getScreenVirtualOff),
luaRegister(getScreenSize),
luaRegister(inv_isFull),
luaRegister(inv_getMaxAmount),
luaRegister(inv_getAmount),
luaRegister(inv_add),
luaRegister(inv_getGfx),
luaRegister(inv_remove),
luaRegister(inv_getType),
luaRegister(inv_getDisplayName),
luaRegister(inv_pickupEffect),
luaRegister(learnRecipe),
luaRegister(createDebugText),
luaRegister(createBitmapText),
luaRegister(text_setText),
luaRegister(text_setFontSize),
luaRegister(text_setWidth),
luaRegister(loadShader),
luaRegister(createShader),
luaRegister(shader_setAsAfterEffect),
luaRegister(shader_setNumAfterEffects),
luaRegister(shader_setFloat),
luaRegister(shader_setInt),
luaRegister(shader_delete),
luaRegister(isQuad),
luaRegister(isNode),
luaRegister(isObject),
@ -8392,6 +8877,7 @@ static const struct {
{"entity_rotateTo", l_entity_rotate},
{"entity_setColor", l_entity_color},
{"entity_setInternalOffset", l_entity_internalOffset},
{"getIngredientGfx", l_inv_getGfx},
{"bone_setColor", l_bone_color},
@ -9033,6 +9519,7 @@ static const struct {
luaConstant(DT_CRUSH),
luaConstant(DT_SPIKES),
luaConstant(DT_STEAM),
luaConstant(DT_WALLHURT),
luaConstant(FRAME_TIME),
@ -9060,6 +9547,10 @@ static const struct {
luaConstant(OT_INVISIBLEIN),
luaConstant(OT_HURT),
luaConstant(OT_INVISIBLEENT),
luaConstant(SEE_MAP_NEVER),
luaConstant(SEE_MAP_DEFAULT),
luaConstant(SEE_MAP_ALWAYS),
};
//============================================================================================
@ -9613,6 +10104,41 @@ bool Script::call(const char *name, void *param1, void *param2, void *param3, fl
return true;
}
bool Script::call(const char *name, const char *param, bool *ret)
{
lookupFunc(name);
lua_pushstring(L, param);
if (!doCall(1, 1))
return false;
*ret = lua_toboolean(L, -1);
lua_pop(L, 1);
return true;
}
bool Script::call(const char *name, const char *param, std::string *ret)
{
lookupFunc(name);
lua_pushstring(L, param);
if (!doCall(1, 1))
return false;
*ret = getString(L, -1);
lua_pop(L, 1);
return true;
}
bool Script::call(const char *name, const char *param1, const char *param2, const char *param3, std::string *ret)
{
lookupFunc(name);
lua_pushstring(L, param1);
lua_pushstring(L, param2);
lua_pushstring(L, param3);
if (!doCall(3, 1))
return false;
*ret = getString(L, -1);
lua_pop(L, 1);
return true;
}
int Script::callVariadic(const char *name, lua_State *fromL, int nparams, void *param)
{
int oldtop = lua_gettop(L);

View file

@ -60,6 +60,12 @@ public:
bool call(const char *name, void *param1, void *param2, void *param3, void *param4);
// boolean = function(pointer, pointer, pointer, number, number, number, number, pointer)
bool call(const char *name, void *param1, void *param2, void *param3, float param4, float param5, float param6, float param7, void *param8, bool *ret1);
// boolean = function(string)
bool call(const char *name, const char *param, bool *ret);
// string = function(string)
bool call(const char *name, const char *param, std::string *ret);
// string = function(string, string, string)
bool call(const char *name, const char *param1, const char *param2, const char *param3, std::string *ret);
// function(pointer, ...) - anything that is already on the stack is forwarded. Results are left on the stack.
// Returns how many values the called function returned, or -1 in case of error.
int callVariadic(const char *name, lua_State *L, int nparams, void *param);

View file

@ -759,32 +759,6 @@ void ScriptedEntity::songNoteDone(int note, float len)
}
}
bool ScriptedEntity::isEntityInside()
{
bool v = false;
int avatars = 0;
FOR_ENTITIES(i)
{
Entity *e = *i;
if (e->getEntityType() == ET_AVATAR)
avatars ++;
if (e && e->life == 1 && e != this && e->ridingOnEntity != this)
{
if (isCoordinateInside(e->position))
{
/*
Vector diff = (e->position - position);
diff.setLength2D(100);
e->vel += diff;
*/
v = true;
}
}
}
return v;
}
void ScriptedEntity::becomeSolid()
{
//vel = 0;

View file

@ -68,7 +68,6 @@ public:
typedef std::vector<Strand*> Strands;
Strands strands;
int strandSpacing;
bool isEntityInside();
void becomeSolid();
std::string deathParticleEffect;

View file

@ -342,6 +342,7 @@ Shot::Shot() : Quad(), Segmented(0,0)
fired = false;
target = 0;
dead = false;
enqueuedForDelete = false;
shotIdx = shots.size();
shots.push_back(this);
}
@ -487,7 +488,6 @@ void Shot::setLifeTime(float l)
void Shot::onEndOfLife()
{
destroySegments(0.2);
deleteShots.push_back(this);
dead = true;
if (emitter)
@ -495,6 +495,12 @@ void Shot::onEndOfLife()
emitter->killParticleEffect();
emitter = 0;
}
if (!enqueuedForDelete)
{
enqueuedForDelete = true;
deleteShots.push_back(this);
}
}
void Shot::doHitEffects()
@ -778,7 +784,7 @@ bool Shot::isObstructed(float dt) const
void Shot::onUpdate(float dt)
{
if (dsq->game->isPaused()) return;
if (dsq->continuity.getWorldType() != WT_NORMAL) return;
if (dsq->game->isWorldPaused()) return;
if (!shotData) return;

View file

@ -128,7 +128,6 @@ public:
protected:
float waveTimer;
bool fired;
void suicide();
@ -141,6 +140,8 @@ protected:
void onEndOfLife();
bool dead;
bool fired;
bool enqueuedForDelete;
void onUpdate(float dt);
private:

View file

@ -41,7 +41,7 @@ void SteamRender::onUpdate(float dt)
void SteamRender::onRender()
{
#ifdef BBGE_BUILD_OPENGL
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
//int qs = 0;
for (Path *p = dsq->game->getFirstPathOfType(PATH_STEAM); p; p = p->nextOfType)
@ -121,7 +121,7 @@ void SteamRender::onRender()
}
}
glEnable(GL_CULL_FACE);
//glEnable(GL_CULL_FACE);
#endif
}

View file

@ -41,6 +41,9 @@ void StringBank::load()
fname = localisePath(dsq->mod.getPath() + "stringbank.txt", dsq->mod.getPath());
_load(fname);
}
if(stringMap.empty())
exit_error("Failed to load data/stringbank.txt");
}
void StringBank::_load(const std::string &file)

View file

@ -91,12 +91,6 @@ void UserSettings::save()
TiXmlElement xml_video("Video");
{
TiXmlElement xml_shader("Shader");
{
xml_shader.SetAttribute("num", video.shader);
}
xml_video.InsertEndChild(xml_shader);
TiXmlElement xml_blur("Blur");
{
xml_blur.SetAttribute("on", video.blur);
@ -413,8 +407,6 @@ void UserSettings::load(bool doApply, const std::string &overrideFile)
TiXmlElement *xml_video = doc.FirstChildElement("Video");
if (xml_video)
{
readInt(xml_video, "Shader", "num", &video.shader);
readInt(xml_video, "Blur", "on", &video.blur);
readInt(xml_video, "NoteEffects", "on", &video.noteEffects);

View file

@ -100,7 +100,6 @@ public:
numParticles = 2048;
parallaxOn0 = parallaxOn1 = parallaxOn2 = 1;
saveSlotScreens = 1;
shader = 0;
blur = 1;
noteEffects = 0;
fpsSmoothing = 30;
@ -115,7 +114,6 @@ public:
displaylists = 0;
worldMapRevealMethod = 0;
}
int shader;
int blur;
int noteEffects;
int fpsSmoothing;

View file

@ -82,6 +82,14 @@ void Web::setPoint(int pt, const Vector &v)
points[pt] = v;
}
Vector Web::getPoint(int pt) const
{
Vector v;
if (pt >= 0 || pt < points.size())
v = points[pt];
return v;
}
int Web::getNumPoints()
{
return points.size();
@ -150,7 +158,7 @@ void Web::onRender()
//glDisable(GL_BLEND);
glLineWidth(4);
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_LINES);

View file

@ -30,6 +30,7 @@ public:
Web();
int addPoint(const Vector &point = Vector(0,0));
void setPoint(int pt, const Vector &v);
Vector getPoint(int pt) const;
void setParentEntity(Entity *e);
int getNumPoints();
typedef std::list<Web*> Webs;

View file

@ -266,9 +266,9 @@ protected:
q->setBlendType(BLEND_ADD);
addChild(q, PM_POINTER);
std::ostringstream os;
os << "children: " << children.size();
debugLog(os.str());
//std::ostringstream os;
//os << "children: " << children.size();
//debugLog(os.str());
}
else
{

View file

@ -32,9 +32,9 @@ Effect::Effect()
AfterEffectManager::AfterEffectManager(int xDivs, int yDivs)
{
active = false;
activeShader = AS_NONE;
numEffects = 0;
bRenderGridPoints = true;
shaderPipeline.resize(10, 0);
screenWidth = core->getWindowWidth();
screenHeight = core->getWindowHeight();
@ -44,45 +44,10 @@ AfterEffectManager::AfterEffectManager(int xDivs, int yDivs)
drawGrid = 0;
#ifdef BBGE_BUILD_OPENGL
this->xDivs = xDivs;
this->yDivs = yDivs;
//cameraPointer = nCameraPointer;
//Asssuming the resolutions values are > 256 and < 2048
//Set the texture heights and widths
if (core->frameBuffer.isInited())
{
textureWidth = core->frameBuffer.getWidth();
textureHeight = core->frameBuffer.getHeight();
}
else
{
if (screenWidth <= 512)
textureWidth = 512;
else if (screenWidth <= 1024)
textureWidth = 1024;
else
textureWidth = 2048;
if (screenHeight <= 512)
textureHeight = 512;
else if (screenHeight <= 1024)
textureHeight = 1024;
else
textureHeight = 2048;
}
//create our texture
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, textureWidth, textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
#endif
//BuildMip();
reloadDevice();
if (xDivs != 0 && yDivs != 0)
{
@ -98,14 +63,9 @@ AfterEffectManager::AfterEffectManager(int xDivs, int yDivs)
void AfterEffectManager::loadShaders()
{
/*
blurShader.load("data/shaders/stan.vert", "data/shaders/blur.frag");
bwShader.load("data/shaders/stan.vert", "data/shaders/bw.frag");
washoutShader.load("data/shaders/stan.vert", "data/shaders/washout.frag");
//motionBlurShader.load("data/shaders/stan.vert", "data/shaders/hoblur.frag");
motionBlurShader.load("data/shaders/stan.vert", "data/shaders/blur.frag");
glowShader.load("data/shaders/stan.vert", "data/shaders/glow.frag");
*/
deleteShaders();
// ...Load shaders here...
}
AfterEffectManager::~AfterEffectManager()
@ -120,6 +80,7 @@ AfterEffectManager::~AfterEffectManager()
delete[] drawGrid;
}
deleteEffects();
deleteShaders();
}
void AfterEffectManager::deleteEffects()
@ -137,6 +98,21 @@ void AfterEffectManager::deleteEffects()
openSpots.pop();
}
void AfterEffectManager::deleteShaders()
{
for(size_t i = 0; i < shaderPipeline.size(); ++i)
shaderPipeline[i] = 0;
for(size_t i = 0; i < loadedShaders.size(); ++i)
{
if(loadedShaders[i])
{
delete loadedShaders[i];
loadedShaders[i] = 0;
}
}
}
void AfterEffectManager::clear()
{
deleteEffects();
@ -190,49 +166,20 @@ void AfterEffectManager::destroyEffect(int id)
openSpots.push(id);
}
void AfterEffectManager::capture()
{
/*
#ifdef BBGE_BUILD_OPENGL
glBindTexture(GL_TEXTURE_2D,texture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screenWidth, screenHeight);
#endif
*/
if (core->frameBuffer.isInited())
{
core->frameBuffer.endCapture();
//core->enable2D(core->pixelScale);
}
else
{
#ifdef BBGE_BUILD_OPENGL
glBindTexture(GL_TEXTURE_2D,texture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screenWidth, screenHeight);
#endif
}
//glDisable(GL_TEXTURE_2D);
}
void AfterEffectManager::render()
{
assert(core->frameBuffer.isInited());
#ifdef BBGE_BUILD_OPENGL
glPushMatrix();
//glDisable(GL_BLEND);
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDisable (GL_ALPHA_TEST);
glDisable(GL_BLEND);
capture();
core->frameBuffer.endCapture();
glTranslatef(core->cameraPos.x, core->cameraPos.y, 0);
glScalef(core->invGlobalScale, core->invGlobalScale,0);
/*
static float angle;
angle += 0.03f;
*/
//glRotatef(angle, 0, 0, 1);
//glColor4f(1,1,1,0.75);
glColor4f(1,1,1,1);
renderGrid();
//renderGridPoints();
@ -240,86 +187,49 @@ void AfterEffectManager::render()
#endif
}
void AfterEffectManager::setActiveShader(ActiveShader as)
{
activeShader = as;
}
void AfterEffectManager::renderGrid()
{
#ifdef BBGE_BUILD_OPENGL
//glBindTexture(GL_TEXTURE_2D, texture);
if (core->frameBuffer.isInited())
core->frameBuffer.bindTexture();
else
glBindTexture(GL_TEXTURE_2D, texture);
//bwShader.bind();
int firstShader = -1;
int lastShader = -1;
Shader *activeShader = 0;
if (core->frameBuffer.isInited())
for (size_t i = 0; i < shaderPipeline.size(); ++i)
{
switch(this->activeShader)
if(shaderPipeline[i])
{
case AS_BLUR:
activeShader = &blurShader;
break;
case AS_BW:
activeShader = &bwShader;
break;
case AS_WASHOUT:
activeShader = &washoutShader;
break;
case AS_MOTIONBLUR:
activeShader = &motionBlurShader;
break;
case AS_GLOW:
activeShader = &glowShader;
break;
if(firstShader < 0)
{
firstShader = i;
activeShader = shaderPipeline[i];
}
lastShader = i;
}
}
if (activeShader)
activeShader->bind();
screenWidth = core->getWindowWidth();
screenHeight = core->getWindowHeight();
/*
float percentX, percentY;
percentX = 1;
percentY = 0.5;
*/
/*
percentX = (float)textureWidth/(float)screenWidth;
percentY = (float)textureHeight/(float)screenHeight;
*/
float percentX, percentY;
percentX = (float)screenWidth/(float)textureWidth;
percentY = (float)screenHeight/(float)textureHeight;
/*
if (screenWidth <= textureWidth)
{
percentX = (float)screenWidth/(float)textureWidth;
percentY = (float)screenHeight/(float)textureHeight;
}
else
{
percentY = 10;
}
*/
int vw = core->getVirtualWidth();
int vh = core->getVirtualHeight();
int offx = -core->getVirtualOffX();
int offy = -core->getVirtualOffY();
core->frameBuffer.bindTexture();
if(activeShader)
{
activeShader->bind();
activeShader->setInt("tex", 0);
if(firstShader != lastShader)
backupBuffer.startCapture();
}
//float div = xDivs;
for (int i = 0; i < (xDivs-1); i++)
{
@ -347,6 +257,56 @@ void AfterEffectManager::renderGrid()
}
}
if (activeShader)
activeShader->unbind();
float width2 = float(vw)/2;
float height2 = float(vh)/2;
if(firstShader != lastShader)
{
// From here on: secondary shader passes.
// We just outputted to the backup buffer...
FrameBuffer *fbIn = &core->frameBuffer;
FrameBuffer *fbOut = &backupBuffer;
for(int i = firstShader + 1; i <= lastShader; ++i)
{
activeShader = shaderPipeline[i];
if(!activeShader)
continue;
// Swap and exchange framebuffers. The old output buffer serves as texture input for the other one
fbOut->endCapture();
std::swap(fbIn, fbOut);
fbIn->bindTexture();
// If this is the last pass, do not render to a frame buffer again
if(i != lastShader)
fbOut->startCapture();
activeShader->bind();
activeShader->setInt("tex", 0);
// note that offx, offy are negative here!
glBegin(GL_QUADS);
glTexCoord2d(0.0f, 0.0f);
glVertex3f(offx, vh+offy, 0.0f);
glTexCoord2d(percentX, 0.0f);
glVertex3f( vw+offx, vh+offy, 0.0f);
glTexCoord2d(percentX, percentY);
glVertex3f( vw+offx, offy, 0.0f);
glTexCoord2d(0.0f, percentY);
glVertex3f(offx, offy, 0.0f);
glEnd();
activeShader->unbind();
}
}
// uncomment to render grid points
/*
glBindTexture(GL_TEXTURE_2D, 0);
@ -383,9 +343,6 @@ void AfterEffectManager::renderGrid()
RenderObject::lastTextureApplied = 0;
glBindTexture(GL_TEXTURE_2D, 0);
if (activeShader)
activeShader->unbind();
//bwShader.unbind();
//glActiveTextureARB(GL_TEXTURE0_ARB);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
@ -415,8 +372,8 @@ void AfterEffectManager::renderGridPoints()
void AfterEffectManager::unloadDevice()
{
if (texture)
glDeleteTextures(1,&texture);
backupBuffer.unloadDevice();
deleteShaders();
}
void AfterEffectManager::reloadDevice()
@ -431,22 +388,18 @@ void AfterEffectManager::reloadDevice()
}
else
{
if (screenWidth <= 1024)
textureWidth = 1024;
else
textureWidth = 2048;
if (screenHeight <= 1024)
textureHeight = 1024;
else
textureHeight = 2048;
textureWidth = screenWidth;
sizePowerOf2Texture(textureWidth);
textureHeight = screenHeight;
sizePowerOf2Texture(textureHeight);
}
//create our texture
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, textureWidth, textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
if(backupBuffer.isInited())
backupBuffer.reloadDevice();
else
backupBuffer.init(-1, -1, true);
loadShaders();
}
void AfterEffectManager::addEffect(Effect *e)
@ -598,3 +551,79 @@ void RippleEffect::update(float dt, Vector ** drawGrid, int xDivs, int yDivs)
}
}
}
int AfterEffectManager::loadShaderFile(const char *vert, const char *frag)
{
Shader *sh = new Shader();
sh->load(vert, frag);
if(!sh->isLoaded())
{
delete sh;
return 0;
}
return _insertShader(sh);
}
int AfterEffectManager::loadShaderSrc(const char *vert, const char *frag)
{
Shader *sh = new Shader();
sh->loadSrc(vert, frag);
if(!sh->isLoaded())
{
delete sh;
return 0;
}
return _insertShader(sh);
}
Shader *AfterEffectManager::getShaderPtr(int handle)
{
size_t idx = handle - 1;
return idx < loadedShaders.size() ? loadedShaders[idx] : 0;
}
void AfterEffectManager::setShaderPipelineSize(size_t size)
{
shaderPipeline.resize(size, 0);
}
bool AfterEffectManager::setShaderPipelinePos(int handle, size_t pos)
{
if(pos < shaderPipeline.size())
{
shaderPipeline[pos] = getShaderPtr(handle);
return true;
}
return false;
}
// returns handle (= index + 1)
int AfterEffectManager::_insertShader(Shader *sh)
{
for(size_t i = 0; i < loadedShaders.size(); ++i)
{
if(!loadedShaders[i])
{
loadedShaders[i] = sh;
return i+1;
}
}
loadedShaders.push_back(sh);
return loadedShaders.size();
}
void AfterEffectManager::unloadShader(int handle)
{
Shader *sh = getShaderPtr(handle);
if(!sh)
return;
for(size_t i = 0; i < shaderPipeline.size(); ++i)
if(shaderPipeline[i] == sh)
shaderPipeline[i] = 0;
size_t idx = handle - 1;
loadedShaders[idx] = 0;
delete sh;
}

View file

@ -72,16 +72,6 @@ public:
float time;
};
enum ActiveShader
{
AS_NONE = 0,
AS_BLUR ,
AS_BW ,
AS_WASHOUT ,
AS_MOTIONBLUR ,
AS_GLOW
};
class AfterEffectManager
{
public:
@ -96,12 +86,12 @@ public:
void resetGrid();
void capture();
void render();
void renderGrid();
void renderGridPoints();
void loadShaders();
void deleteShaders();
void unloadDevice();
void reloadDevice();
@ -111,12 +101,6 @@ public:
bool active;
void setActiveShader(ActiveShader as);
#ifdef BBGE_BUILD_OPENGL
GLuint texture;
#endif
bool bRenderGridPoints;
int numEffects;
@ -124,11 +108,23 @@ public:
int screenWidth, screenHeight;
int textureWidth, textureHeight;
Shader blurShader, bwShader, washoutShader, motionBlurShader, glowShader;
Vector ** drawGrid;
ActiveShader activeShader;
// returns handle > 0 on success
int loadShaderFile(const char *vert, const char *frag);
int loadShaderSrc(const char *vert, const char *frag);
Shader *getShaderPtr(int handle);
void setShaderPipelineSize(size_t size);
bool setShaderPipelinePos(int handle, size_t pos);
void unloadShader(int handle);
protected:
int _insertShader(Shader *sh);
std::vector<Shader*> shaderPipeline; // Shaders are applied in this order. Can contain the same pointer more than once.
std::vector<Shader*> loadedShaders;
FrameBuffer backupBuffer;
};

View file

@ -5,7 +5,7 @@
#define BBGE_BUILD_SDL 1
#define BBGE_BUILD_FRAMEBUFFER 1
//#define BBGE_BUILD_SHADERS 1
#define BBGE_BUILD_SHADERS 1
#define BBGE_BUILD_OPENGL 1
#define BBGE_BUILD_OPENGL_DYNAMIC 1
#define BBGE_BUILD_FMOD_OPENAL_BRIDGE 1

View file

@ -291,8 +291,7 @@ bool exists(const std::string &f, bool makeFatal, bool skipVFS)
if (makeFatal && !e)
{
errorLog(std::string("Could not open [" + f + "]"));
exit(0);
exit_error("Could not open [" + f + "]");
}
return e;
@ -301,7 +300,7 @@ bool exists(const std::string &f, bool makeFatal, bool skipVFS)
void drawCircle(float radius, int stepSize)
{
#ifdef BBGE_BUILD_OPENGL
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
glBegin(GL_POLYGON);
{
@ -312,14 +311,14 @@ void drawCircle(float radius, int stepSize)
}
glEnd();
glEnable(GL_CULL_FACE);
//glEnable(GL_CULL_FACE);
#endif
}
void fatalError(const std::string &message)
void exit_error(const std::string &message)
{
msg(message);
exit(0);
errorLog(message);
exit(1);
}
std::string parseCommand(const std::string &line, const std::string &command)
@ -424,8 +423,7 @@ void errorLog(const std::string &s)
}
else
{
//msg("Core Not Initialized");
//MessageBox(0, s.c_str(), "ErrorLog (Core Not Initalized)", MB_OK);
messageBox("Error!", s);
}
}
@ -775,17 +773,18 @@ std::vector<std::string> getFileList(std::string path, std::string type, int par
return list;
}
std::string msg(const std::string &message)
void messageBox(const std::string& title, const std::string &msg)
{
core->msg(message);
return message;
}
void msgVector(const std::string &name, const Vector &vec)
{
std::ostringstream os;
os << name << ": (" << vec.x <<", " << vec.y << ", " << vec.z << ")";
msg (os.str());
#ifdef BBGE_BUILD_WINDOWS
MessageBox (0,msg.c_str(),title.c_str(),MB_OK);
#elif defined(BBGE_BUILD_MACOSX)
cocoaMessageBox(title, msg);
#elif defined(BBGE_BUILD_UNIX)
// !!! FIXME: probably don't want the whole GTK+ dependency in here...
fprintf(stderr, "%s: %s\n", title.c_str(), msg.c_str());
#else
#error Please define your platform.
#endif
}
Vector getNearestPointOnLine(Vector a, Vector b, Vector c)

View file

@ -257,11 +257,9 @@ bool isVectorInRect(const Vector &vec, const Vector &coord1, const Vector &coord
std::string parseCommand(const std::string &line, const std::string &command);
std::string msg(const std::string &message);
void messageBox(const std::string &title, const std::string& msg);
void msgVector(const std::string &name, const Vector &vec);
void fatalError(const std::string &message);
void exit_error(const std::string &message);
unsigned hash(const std::string &string);

View file

@ -317,7 +317,7 @@ void BitmapText::onRender()
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
*/
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
//glScalef(1, -1, 0);
@ -374,7 +374,7 @@ void BitmapText::onRender()
}
}
glEnable(GL_CULL_FACE);
//glEnable(GL_CULL_FACE);
glBindTexture(GL_TEXTURE_2D, 0);
#endif

View file

@ -818,7 +818,7 @@ bool Core::getMetaState()
void Core::errorLog(const std::string &s)
{
messageBox("Message", s);
messageBox("Error!", s);
debugLog(s);
}
@ -828,16 +828,7 @@ void cocoaMessageBox(const std::string &title, const std::string &msg);
void Core::messageBox(const std::string &title, const std::string &msg)
{
#ifdef BBGE_BUILD_WINDOWS
MessageBox (0,msg.c_str(),title.c_str(),MB_OK);
#elif defined(BBGE_BUILD_MACOSX)
cocoaMessageBox(title, msg);
#elif defined(BBGE_BUILD_UNIX)
// !!! FIXME: probably don't want the whole GTK+ dependency in here...
fprintf(stderr, "%s: %s\n", title.c_str(), msg.c_str());
#else
#error Please define your platform.
#endif
::messageBox(title, msg);
}
void Core::debugLog(const std::string &s)
@ -1276,7 +1267,7 @@ void Core::init()
if((SDL_Init(0))==-1)
{
exit(0);
exit_error("Failed to init SDL");
}
#endif
@ -1849,11 +1840,13 @@ void Core::setSDLGLAttributes()
#define GLAPIENTRY
#endif
unsigned int Core::dbg_numRenderCalls = 0;
#ifdef BBGE_BUILD_OPENGL_DYNAMIC
#define GL_FUNC(ret,fn,params,call,rt) \
extern "C" { \
static ret (GLAPIENTRY *p##fn) params = NULL; \
ret GLAPIENTRY fn params { rt p##fn call; } \
ret GLAPIENTRY fn params { ++Core::dbg_numRenderCalls; rt p##fn call; } \
}
#include "OpenGLStubs.h"
#undef GL_FUNC
@ -1917,16 +1910,15 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync
{
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
{
errorLog(std::string("SDL Error: ") + std::string(SDL_GetError()));
exit(0);
exit_error(std::string("SDL Error: ") + std::string(SDL_GetError()));
}
#if BBGE_BUILD_OPENGL_DYNAMIC
if (SDL_GL_LoadLibrary(NULL) == -1)
{
errorLog(std::string("SDL_GL_LoadLibrary Error: ") + std::string(SDL_GetError()));
std::string err = std::string("SDL_GL_LoadLibrary Error: ") + std::string(SDL_GetError());
SDL_Quit();
exit(0);
exit_error(err);
}
#endif
}
@ -1950,9 +1942,8 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync
{
std::ostringstream os;
os << "Couldn't set resolution [" << width << "x" << height << "]\n" << SDL_GetError();
errorLog(os.str());
SDL_Quit();
exit(0);
exit_error(os.str());
}
#if BBGE_BUILD_OPENGL_DYNAMIC
@ -1960,9 +1951,8 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync
{
std::ostringstream os;
os << "Couldn't load OpenGL symbols we need\n";
errorLog(os.str());
SDL_Quit();
exit(0);
exit_error(os.str());
}
#endif
}
@ -2632,13 +2622,6 @@ void Core::setDockIcon(const std::string &ident)
{
}
void Core::msg(const std::string &message)
{
#ifdef BBGE_BUILD_WINDOWS
MessageBox(0, message.c_str(), "Message", MB_OK);
#endif
}
void Core::setMousePosition(const Vector &p)
{
Vector lp = core->mouse.position;
@ -3015,6 +2998,8 @@ void Core::main(float runTime)
updateCullData();
dbg_numRenderCalls = 0;
if (settings.renderOn)
{
if (verbose) debugLog("dark layer prerender");
@ -3857,10 +3842,6 @@ void Core::render(int startLayer, int endLayer, bool useFrameBufferIfAvail)
int i = renderObjectLayerOrder[c];
if (i == -1) continue;
if ((startLayer != -1 && endLayer != -1) && (i < startLayer || i > endLayer)) continue;
if (afterEffectManager && afterEffectManager->active && i == afterEffectManagerLayer)
{
afterEffectManager->render();
}
if (i == postProcessingFx.layer)
{
@ -3890,6 +3871,11 @@ void Core::render(int startLayer, int endLayer, bool useFrameBufferIfAvail)
}
}
if (afterEffectManager && afterEffectManager->active && i == afterEffectManagerLayer)
{
afterEffectManager->render();
}
RenderObjectLayer *r = &renderObjectLayers[i];
RenderObject::rlayer = r;
if (r->visible)
@ -4844,14 +4830,13 @@ void Core::setupFileAccess()
debugLog("Init VFS...");
if(!ttvfs::checkCompat())
exit(1);
exit_error("ttvfs not compatible");
vfs.AddArchiveLoader(new ttvfs::VFSZipArchiveLoader);
if(!vfs.LoadFileSysRoot(false))
{
errorLog("Failed to setup file access");
exit(1);
exit_error("Failed to setup file access");
}
vfs.Prepare();

View file

@ -1175,8 +1175,6 @@ public:
void saveSizedScreenshotTGA(const std::string &filename, int sz, int crop34);
void saveCenteredScreenshotTGA(const std::string &filename, int sz);
virtual void msg(const std::string &message);
bool minimized;
std::string getEnqueuedJumpState();
int cullRadius;
@ -1310,6 +1308,7 @@ public:
int zgaSave(const char *filename, short int width, short int height, unsigned char pixelDepth, unsigned char *imageData);
volatile int dbg_numThreadDecoders;
static unsigned int dbg_numRenderCalls;
protected:

View file

@ -306,7 +306,7 @@ void Emitter::onRender()
if (data.flipH || (data.copyParentFlip && (pe->isfh() || (pe->getParent() && pe->getParent()->isfh()))))
{
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
glRotatef(180, 0, 1, 0);
}

View file

@ -34,6 +34,11 @@ Precacher::~Precacher()
errorLog ("Precacher shutdown unclean");
}
void Precacher::setBaseDir(const std::string& dir)
{
basedirOverride = dir;
}
void Precacher::clean()
{
for (unsigned int i = 0; i < renderObjects.size(); i++)
@ -88,6 +93,8 @@ void Precacher::precacheTex(const std::string &tex)
}
if (tex.empty()) return;
std::string basedir = basedirOverride.empty() ? core->getBaseTextureDirectory() : basedirOverride;
if (core->debugLogTextures)
debugLog("PRECACHING: " + tex);
@ -99,7 +106,7 @@ void Precacher::precacheTex(const std::string &tex)
int loc = tex.find('*');
std::string path = tex.substr(0, loc);
std::string type = tex.substr(loc+1, tex.size());
path = core->getBaseTextureDirectory() + path;
path = basedir + path;
forEachFile(path, type, precacherCallback, (intptr_t)this);
return;
}
@ -108,9 +115,9 @@ void Precacher::precacheTex(const std::string &tex)
if (loadProgressCallback)
loadProgressCallback();
std::string t = tex;
if (tex.find(core->getBaseTextureDirectory()) != std::string::npos)
if (tex.find(basedir) != std::string::npos)
{
t = tex.substr(core->getBaseTextureDirectory().size(), tex.size());
t = tex.substr(basedir.size(), tex.size());
}
Quad *q = new Quad;
q->setTexture(t);

View file

@ -32,11 +32,13 @@ public:
void precacheList(const std::string &list, void progressCallback() = NULL);
void clean();
void loadTextureRange(const std::string &file, const std::string &type, int start, int end);
void setBaseDir(const std::string& dir);
std::vector<RenderObject*> renderObjects;
private:
bool cleaned;
void (*loadProgressCallback)();
std::string basedirOverride;
};
#endif

View file

@ -499,7 +499,7 @@ void Quad::onRender()
if (!strip.empty())
{
//glDisable(GL_BLEND);gggg
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
const float texBits = 1.0f / (strip.size()-1);
@ -517,7 +517,7 @@ void Quad::onRender()
}
glEnd();
glEnable(GL_CULL_FACE);
//glEnable(GL_CULL_FACE);
glBindTexture( GL_TEXTURE_2D, 0 );
glColor4f(1,0,0,1);
glPointSize(64);
@ -802,6 +802,7 @@ void Quad::onSetTexture()
PauseQuad::PauseQuad() : Quad(), pauseLevel(0)
{
addType(SCO_PAUSEQUAD);
}
void PauseQuad::onUpdate(float dt)

View file

@ -59,7 +59,7 @@ void QuadTrail::onRender()
if (numPoints < 2) return;
#ifdef BBGE_BUILD_OPENGL
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
int c = 0;
Vector p, diff, dl, dr;
Vector lastPoint;

View file

@ -629,7 +629,7 @@ void RenderObject::renderCall()
glTranslatef(position.x, position.y, position.z);
if (isfh())
{
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
glRotatef(180, 0, 1, 0);
}
@ -655,7 +655,7 @@ void RenderObject::renderCall()
glTranslatef(pos.x, pos.y, pos.z);
if (isfh())
{
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
glRotatef(180, 0, 1, 0);
}
glRotatef(rotation.z+rotationOffset.z, 0, 0, 1);
@ -714,7 +714,7 @@ void RenderObject::renderCall()
glRotatef(rotation.z+rotationOffset.z, 0, 0, 1);
if (isfh())
{
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
glRotatef(180, 0, 1, 0);
}
#endif

View file

@ -105,7 +105,7 @@ void RoundedRect::onRender()
//glBindTexture(GL_TEXTURE_2D, 0);
int w2 = width/2;
int h2 = height/2;
glDisable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
float iter = 0.1f;
glBegin(GL_QUADS);
@ -167,7 +167,7 @@ void RoundedRect::onRender()
glEnd();
glEnable(GL_CULL_FACE);
//glEnable(GL_CULL_FACE);
}
void RoundedRect::show()

View file

@ -37,6 +37,8 @@ static const char *scriptObjTypeNames[] =
/* (1 << 9) */ "Path/Node",
/* (1 <<10) */ "Quad",
/* (1 <<11) */ "Text",
/* (1 <<12) */ "PauseQuad",
/* (1 <<13) */ "Shader",
NULL
};

View file

@ -39,6 +39,8 @@ enum ScriptObjectType
SCO_PATH = 0x0200,
SCO_QUAD = 0x0400,
SCO_TEXT = 0x0800,
SCO_PAUSEQUAD = 0x1000,
SCO_SHADER = 0x2000,
SCO_FORCE_32BIT = 0xFFFFFFFF
};

View file

@ -18,10 +18,9 @@ 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 "Shader.h"
#ifdef BBGE_BUILD_WINDOWS
#include <sys/stat.h>
#endif
#include "algorithmx.h"
#ifdef BBGE_BUILD_SHADERS
// GL_ARB_shader_objects
@ -36,8 +35,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL;
PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL;
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL;
PFNGLUNIFORM4FARBPROC glUniform4fARB = NULL;
PFNGLUNIFORM1IARBPROC glUniform1iARB = NULL;
PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL;
PFNGLUNIFORM1FVARBPROC glUniform1fvARB = NULL;
PFNGLUNIFORM2FVARBPROC glUniform2fvARB = NULL;
PFNGLUNIFORM3FVARBPROC glUniform3fvARB = NULL;
PFNGLUNIFORM4FVARBPROC glUniform4fvARB = NULL;
PFNGLUNIFORM1IVARBPROC glUniform1ivARB = NULL;
PFNGLUNIFORM2IVARBPROC glUniform2ivARB = NULL;
PFNGLUNIFORM3IVARBPROC glUniform3ivARB = NULL;
PFNGLUNIFORM4IVARBPROC glUniform4ivARB = NULL;
#endif
bool Shader::_wasInited = false;
@ -73,22 +80,6 @@ void Shader::staticInit()
}
else
{
#ifdef BBGE_BUILD_GLFW
glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)glfwGetProcAddress("glCreateProgramObjectARB");
glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)glfwGetProcAddress("glDeleteObjectARB");
glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)glfwGetProcAddress("glUseProgramObjectARB");
glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)glfwGetProcAddress("glCreateShaderObjectARB");
glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)glfwGetProcAddress("glShaderSourceARB");
glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)glfwGetProcAddress("glCompileShaderARB");
glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)glfwGetProcAddress("glGetObjectParameterivARB");
glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)glfwGetProcAddress("glAttachObjectARB");
glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)glfwGetProcAddress("glGetInfoLogARB");
glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)glfwGetProcAddress("glLinkProgramARB");
glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)glfwGetProcAddress("glGetUniformLocationARB");
glUniform4fARB = (PFNGLUNIFORM4FARBPROC)glfwGetProcAddress("glUniform4fARB");
glUniform1iARB = (PFNGLUNIFORM1IARBPROC)glfwGetProcAddress("glUniform1iARB");
#endif
#ifdef BBGE_BUILD_SDL
glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glCreateProgramObjectARB");
glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)SDL_GL_GetProcAddress("glDeleteObjectARB");
@ -101,15 +92,23 @@ void Shader::staticInit()
glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)SDL_GL_GetProcAddress("glGetInfoLogARB");
glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)SDL_GL_GetProcAddress("glLinkProgramARB");
glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)SDL_GL_GetProcAddress("glGetUniformLocationARB");
glUniform4fARB = (PFNGLUNIFORM4FARBPROC)SDL_GL_GetProcAddress("glUniform4fARB");
glUniform1iARB = (PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1iARB");
glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)SDL_GL_GetProcAddress("glGetActiveUniformARB");
glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)SDL_GL_GetProcAddress("glUniform1fvARB");
glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)SDL_GL_GetProcAddress("glUniform2fvARB");
glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)SDL_GL_GetProcAddress("glUniform3fvARB");
glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC)SDL_GL_GetProcAddress("glUniform4fvARB");
glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC)SDL_GL_GetProcAddress("glUniform1ivARB");
glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC)SDL_GL_GetProcAddress("glUniform2ivARB");
glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC)SDL_GL_GetProcAddress("glUniform3ivARB");
glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC)SDL_GL_GetProcAddress("glUniform4ivARB");
#endif
if( !glCreateProgramObjectARB || !glDeleteObjectARB || !glUseProgramObjectARB ||
!glCreateShaderObjectARB || !glCreateShaderObjectARB || !glCompileShaderARB ||
!glGetObjectParameterivARB || !glAttachObjectARB || !glGetInfoLogARB ||
!glLinkProgramARB || !glGetUniformLocationARB || !glUniform4fARB ||
!glUniform1iARB )
!glLinkProgramARB || !glGetUniformLocationARB || !glGetActiveUniformARB ||
!glUniform1fvARB || !glUniform2fvARB || !glUniform3fvARB || !glUniform4fvARB ||
!glUniform1ivARB || !glUniform2ivARB || !glUniform3ivARB || !glUniform4ivARB)
{
glCreateProgramObjectARB = 0;
debugLog("One or more GL_ARB_shader_objects functions were not found");
@ -132,88 +131,35 @@ end:
Shader::Shader()
{
loaded = false;
mode = 0;
numUniforms = -1;
uniformsDirty = false;
#ifdef BBGE_BUILD_OPENGL
g_vertexShader = 0;
g_fragmentShader = 0;
g_programObj = 0;
vx = vy = vz = vw = 0;
g_location_texture = 0;
g_location_mode = 0;
g_location_value = 0;
#endif
}
Shader::~Shader()
{
unload();
}
void Shader::unload()
{
#ifdef BBGE_BUILD_SHADERS
if (!_useShaders)
return;
if (g_vertexShader)
glDeleteObjectARB( g_vertexShader );
if (g_fragmentShader)
glDeleteObjectARB( g_fragmentShader );
if (g_programObj)
{
glDeleteObjectARB( g_programObj );
g_programObj = 0;
}
#endif
}
bool Shader::isLoaded()
bool Shader::isLoaded() const
{
return loaded;
}
void Shader::setMode(int mode)
{
this->mode = mode;
}
void Shader::setValue(float x, float y, float z, float w)
{
vx = x;
vy = y;
vz = z;
vw = w;
}
unsigned char *readShaderFile( const char *fileName )
{
debugLog("readShaderFile()");
#ifdef BBGE_BUILD_WINDOWS
FILE *file = fopen( fileName, "r" ); // FIXME: should this code ever be re-activated, adjust to VFS! -- fg
if( file == NULL )
{
errorLog("Cannot open shader file!");
return 0;
}
struct _stat fileStats;
if( _stat( fileName, &fileStats ) != 0 )
{
errorLog("Cannot get file stats for shader file!");
return 0;
}
unsigned char *buffer = new unsigned char[fileStats.st_size];
int bytes = fread( buffer, 1, fileStats.st_size, file );
buffer[bytes] = 0;
fclose( file );
debugLog("End readShaderFile()");
return buffer;
#else
debugLog("End readShaderFile()");
return 0;
#endif
return g_programObj != 0;
}
void Shader::reload()
@ -227,12 +173,7 @@ void Shader::bind()
if (!_useShaders)
return;
glUseProgramObjectARB(g_programObj);
if( g_location_texture != -1 )
glUniform1iARB( g_location_texture, 0 );
if ( g_location_mode )
glUniform1iARB( g_location_mode, mode);
if ( g_location_value )
glUniform4fARB( g_location_value, vx, vy, vz, vw);
_flushUniforms();
#endif
}
@ -241,142 +182,273 @@ void Shader::unbind()
#ifdef BBGE_BUILD_SHADERS
if (!_useShaders)
return;
glUseProgramObjectARB( NULL );
glUseProgramObjectARB(0);
#endif
}
unsigned int Shader::_compileShader(int type, const char *src, char *errbuf, size_t errbufsize)
{
#ifdef BBGE_BUILD_SHADERS
GLint compiled = 0;
GLhandleARB handle = glCreateShaderObjectARB(type);
if(!handle)
{
std::ostringstream os;
os << "Failed to create shader object of type " << type;
debugLog(os.str());
return 0;
}
glShaderSourceARB( handle, 1, &src, NULL );
glCompileShaderARB( handle);
glGetObjectParameterivARB(handle, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
glGetInfoLogARB(handle, errbufsize, NULL, errbuf);
if(!compiled)
{
glDeleteObjectARB(handle);
handle = 0;
}
GLint err = glGetError();
if(err != GL_NO_ERROR)
{
std::ostringstream os;
os << "Shader::_compileShader: Unexpected error " << err;
errorLog(os.str());
}
return handle;
#endif
return 0;
}
void Shader::load(const std::string &file, const std::string &fragFile)
{
staticInit();
loaded = false;
#ifdef BBGE_BUILD_SHADERS
if(!_useShaders)
return;
debugLog("Shader::load("+file+", "+fragFile+")");
g_location_texture = 0;
g_location_mode = 0;
g_location_value = 0;
debugLog("Shader::load 1");
this->vertFile = file;
this->fragFile = fragFile;
//
// If the required extension is present, get the addresses of its
// functions that we wish to use...
//
const char *vertexShaderStrings[1];
const char *fragmentShaderStrings[1];
GLint bVertCompiled;
GLint bFragCompiled;
GLint bLinked;
char *vertCode = file.length() ? readFile(file) : NULL;
char *fragCode = fragFile.length() ? readFile(fragFile) : NULL;
loadSrc(vertCode, fragCode);
delete [] vertCode;
delete [] fragCode;
}
void Shader::loadSrc(const char *vertCode, const char *fragCode)
{
staticInit();
unload();
if(!_useShaders)
return;
#ifdef BBGE_BUILD_SHADERS
char str[4096];
GLhandleARB vertexShader = 0;
GLhandleARB fragmentShader = 0;
//
// Create the vertex shader...
//
debugLog("Shader::load 2");
g_vertexShader = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
unsigned char *vertexShaderAssembly = readShaderFile( file.c_str() );
vertexShaderStrings[0] = (char*)vertexShaderAssembly;
glShaderSourceARB( g_vertexShader, 1, vertexShaderStrings, NULL );
glCompileShaderARB( g_vertexShader);
delete[] vertexShaderAssembly;
glGetObjectParameterivARB( g_vertexShader, GL_OBJECT_COMPILE_STATUS_ARB,
&bVertCompiled );
if( bVertCompiled == false )
//if (true)
if(vertCode && *vertCode && !(vertexShader = _compileShader(GL_VERTEX_SHADER_ARB, vertCode, str, sizeof(str))))
{
glGetInfoLogARB(g_vertexShader, sizeof(str), NULL, str);
std::ostringstream os;
os << "Vertex Shader Compile Error: " << str;
debugLog(os.str());
os << "Vertex Shader Compile Error [" << vertFile << "]:\n" << str;
errorLog(os.str());
return;
}
//
// Create the fragment shader...
//
debugLog("Shader::load 3");
g_fragmentShader = glCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB );
unsigned char *fragmentShaderAssembly = readShaderFile( fragFile.c_str() );
fragmentShaderStrings[0] = (char*)fragmentShaderAssembly;
glShaderSourceARB( g_fragmentShader, 1, fragmentShaderStrings, NULL );
glCompileShaderARB( g_fragmentShader );
delete[] fragmentShaderAssembly;
glGetObjectParameterivARB( g_fragmentShader, GL_OBJECT_COMPILE_STATUS_ARB,
&bFragCompiled );
if( bFragCompiled == false )
if(fragCode && *fragCode && !(fragmentShader = _compileShader(GL_FRAGMENT_SHADER_ARB, fragCode, str, sizeof(str))))
{
glGetInfoLogARB( g_fragmentShader, sizeof(str), NULL, str );
std::ostringstream os;
os << "Fragment Shader Compile Error: " << str;
debugLog(os.str());
os << "Fragment Shader Compile Error [" << fragFile << "]:\n" << str;
errorLog(os.str());
return;
}
debugLog("Shader::load 4");
//
// Create a program object and attach the two compiled shaders...
//
g_programObj = glCreateProgramObjectARB();
if (!g_programObj || !g_vertexShader || !g_fragmentShader)
if (!(g_programObj && (vertexShader || fragmentShader)))
{
debugLog("programObj / vertexShader / fragmentShader problem");
errorLog("programObj / vertexShader / fragmentShader problem");
unload();
return;
}
glAttachObjectARB( g_programObj, g_vertexShader );
glAttachObjectARB( g_programObj, g_fragmentShader );
//
// Link the program object and print out the info log...
//
if(vertexShader)
glAttachObjectARB( g_programObj, vertexShader );
if(fragmentShader)
glAttachObjectARB( g_programObj, fragmentShader );
glLinkProgramARB( g_programObj );
// Shader objects will be deleted as soon as the program object is deleted
if(vertexShader)
glDeleteObjectARB(vertexShader);
if(fragmentShader)
glDeleteObjectARB(fragmentShader);
GLint bLinked;
glGetObjectParameterivARB( g_programObj, GL_OBJECT_LINK_STATUS_ARB, &bLinked );
debugLog("Shader::load 5");
if( bLinked == false )
if(!bLinked)
{
glGetInfoLogARB( g_programObj, sizeof(str), NULL, str );
std::ostringstream os;
os << "Shader Linking Error: " << str;
debugLog(os.str());
errorLog(os.str());
unload();
return;
}
//
// Locate some parameters by name so we can set them later...
//
debugLog("Shader::load 6");
g_location_texture = glGetUniformLocationARB( g_programObj, "tex" );
g_location_mode = glGetUniformLocationARB( g_programObj, "mode" );
g_location_value = glGetUniformLocationARB( g_programObj, "value" );
debugLog("Shader::load 7");
loaded = true;
_queryUniforms();
#endif
debugLog("End Shader::load()");
}
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;
case GL_FLOAT_VEC2_ARB: glUniform2fvARB(u->location, 1, u->data.f); break;
case GL_FLOAT_VEC3_ARB: glUniform3fvARB(u->location, 1, u->data.f); break;
case GL_FLOAT_VEC4_ARB: glUniform4fvARB(u->location, 1, u->data.f); break;
case GL_INT: glUniform1ivARB(u->location, 1, u->data.i); break;
case GL_INT_VEC2_ARB: glUniform2ivARB(u->location, 1, u->data.i); break;
case GL_INT_VEC3_ARB: glUniform3ivARB(u->location, 1, u->data.i); break;
case GL_INT_VEC4_ARB: glUniform4ivARB(u->location, 1, u->data.i); break;
}
u->dirty = false;
}
void Shader::_flushUniforms()
{
if(!uniformsDirty)
return;
uniformsDirty = false;
for(size_t i = 0; i < uniforms.size(); ++i)
{
Uniform &u = uniforms[i];
if(u.dirty)
_setUniform(&u);
}
}
// for sorting
bool Shader::_sortUniform(const Uniform& a, const char *bname)
{
return strcmp(a.name, bname) < 0;
}
bool Shader::Uniform::operator< (const Uniform& b) const
{
return Shader::_sortUniform(*this, &b.name[0]);
}
void Shader::_queryUniforms()
{
glGetObjectParameterivARB(g_programObj, GL_OBJECT_ACTIVE_UNIFORMS_ARB , &numUniforms);
if (numUniforms <= 0)
return;
uniforms.reserve(numUniforms);
for (unsigned int i = 0; i < numUniforms; ++i)
{
Uniform u;
GLint size = 0;
GLenum type = 0;
glGetActiveUniformARB(g_programObj, i, sizeof(u.name), NULL, &size, &type, &u.name[0]);
if(!type || !size)
continue;
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);
}
// sort to be able to do binary search later
std::sort(uniforms.begin(), uniforms.end());
}
int Shader::_getUniformIndex(const char *name)
{
// binary search
UniformVec::iterator it = stdx_fg::lower_bound(uniforms.begin(), uniforms.end(), name, _sortUniform);
// because lower_bound returns the first element that compares less, it might not be the correct one
if(it != uniforms.end() && strcmp(it->name, name))
return -1;
return int(it - uniforms.begin());
}
void Shader::setInt(const char *name, int x, int y /* = 0 */, int z /* = 0 */, int w /* = 0 */)
{
#if BBGE_BUILD_SHADERS
if(!g_programObj || numUniforms <= 0)
return;
int idx = _getUniformIndex(name);
if(unsigned(idx) >= uniforms.size())
return;
Uniform& u = uniforms[idx];
u.data.i[0] = x;
u.data.i[1] = y;
u.data.i[2] = z;
u.data.i[3] = w;
u.dirty = true;
uniformsDirty = true;
#endif
}
void Shader::setFloat(const char *name, float x, float y /* = 0 */, float z /* = 0 */, float w /* = 0 */)
{
#if BBGE_BUILD_SHADERS
if(!g_programObj || numUniforms <= 0)
return;
int idx = _getUniformIndex(name);
if(unsigned(idx) >= uniforms.size())
return;
Uniform& u = uniforms[idx];
u.data.f[0] = x;
u.data.f[1] = y;
u.data.f[2] = z;
u.data.f[3] = w;
u.dirty = true;
uniformsDirty = true;
#endif
}

View file

@ -22,36 +22,74 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define BBGE_SHADER_H
#include "Base.h"
#include "ScriptObject.h"
class Shader
{
public:
Shader();
~Shader();
bool isLoaded();
bool isLoaded() const;
void load(const std::string &file, const std::string &fragFile);
void loadSrc(const char *vertCode, const char *fragCode);
void reload();
void unload();
void bind();
void unbind();
void setMode(int mode);
void setValue(float x, float y, float z, float w);
std::string vertFile, fragFile;
void setInt(const char *name, int x, int y = 0, int z = 0, int w = 0);
void setFloat(const char *name, float x, float y = 0, float z = 0, float w = 0);
// TODO: other setters needed?
protected:
std::string vertFile, fragFile;
#ifdef BBGE_BUILD_OPENGL
GLuint g_programObj;
GLuint g_vertexShader;
GLuint g_fragmentShader;
GLuint g_location_texture;
GLuint g_location_mode;
GLuint g_location_value;
int numUniforms;
#endif
int mode;
float vx, vy, vz, vw;
bool loaded;
private:
static void staticInit();
static bool _wasInited;
static bool _useShaders;
static unsigned int _compileShader(int type, const char *src, char *errbuf, size_t errbufsize);
struct Uniform
{
int location; // GL location variable
int type;
bool dirty; // need to flush if true
union
{
struct
{
int i[4];
};
struct
{
float f[4];
};
} data;
char name[32];
bool operator< (const Uniform&) const;
};
static bool _sortUniform(const Uniform& a, const char *bname);
void _queryUniforms();
void _flushUniforms();
void _registerUniform();
void _setUniform(Uniform *u);
int _getUniformIndex(const char *name);
typedef std::vector<Uniform> UniformVec;
UniformVec uniforms;
bool uniformsDirty;
};
#endif

View file

@ -507,8 +507,7 @@ Animation* AnimationLayer::getCurrentAnimation()
{
std::ostringstream os;
os << "skel: " << s->filenameLoaded << " currentAnimation: " << currentAnimation << " is out of range\n error in anim file?";
errorLog(os.str());
exit(-1);
exit_error(os.str());
return 0;
}
return &s->animations[currentAnimation];

View file

@ -279,7 +279,7 @@ void StateManager::registerStateObject(StateObject *stateObject, const std::stri
//getNameFromDerivedClassTypeName(c);
if (stateObject->name.empty())
{
fatalError("StateManager::registerStateObject - Empty name.");
exit_error("StateManager::registerStateObject - Empty name.");
}
if (!stateObjects[stateObject->name])

View file

@ -446,7 +446,6 @@ void Texture::loadPNG(const std::string &file)
width = 64;
height = 64;
Texture::textureError = TEXERR_FILENOTFOUND;
//exit(1);
return;
}
@ -483,7 +482,6 @@ void Texture::loadPNG(const std::string &file)
width = 64;
height = 64;
Texture::textureError = TEXERR_FILENOTFOUND;
//exit(1);
}

View file

@ -306,12 +306,12 @@ Vector VectorPath::getValue(float usePercent)
if (!from && !target)
{
msg ("returning first value");
errorLog("returning first value");
return pathNodes[0].value;
}
else if (!from && target)
{
msg("Unexpected Path node result (UPDATE: Could use current value as from?)");
errorLog("Unexpected Path node result (UPDATE: Could use current value as from?)");
}
else if (from && !target)
{

View file

@ -243,7 +243,7 @@ ADD_DEFINITIONS(-DTIXML_USE_STL=1)
ADD_DEFINITIONS(-DBBGE_SKIP_CONFIG_HEADERS=1) # if this is not defined, it will use .h files to set the necessary defines
ADD_DEFINITIONS(-DBBGE_BUILD_SDL=1)
ADD_DEFINITIONS(-DBBGE_BUILD_FRAMEBUFFER=1)
#ADD_DEFINITIONS(-DBBGE_BUILD_SHADERS=1)
ADD_DEFINITIONS(-DBBGE_BUILD_SHADERS=1)
ADD_DEFINITIONS(-DBBGE_BUILD_OPENGL=1)
ADD_DEFINITIONS(-DBBGE_BUILD_OPENGL_DYNAMIC=1)
ADD_DEFINITIONS(-DBBGE_BUILD_FMOD_OPENAL_BRIDGE=1)

34
ExternalLibs/algorithmx.h Normal file
View file

@ -0,0 +1,34 @@
#ifndef STDXfg_ALGORITHMX_H
#define STDXfg_ALGORITHMX_H
// Some std:: namespace enhancements
#include <algorithm>
namespace stdx_fg {
template <class ForwardIterator, class T, class Compare>
ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& val, Compare comp)
{
ForwardIterator it;
typename std::iterator_traits<ForwardIterator>::difference_type count, step;
count = std::distance(first,last);
while(count > 0)
{
it = first;
step = count/2;
std::advance (it,step);
if (comp(*it, val))
{
first= ++it;
count -= step+1;
}
else
count = step;
}
return first;
}
} // end namespace stdx_fg
#endif

56
files/data/worldmap.txt Normal file
View file

@ -0,0 +1,56 @@
0 1008 MAINAREA 0 5 -0.667596 -1.2 1 1
1 1006 NAIJACAVE 1 2.5 398.484 -188.954 1 1
2 1005 VEDHACAVE 1 2 14.4108 -19.2 1 0.36
3 1015 ABYSS01 0 5 319.096 639.447 0 1
4 1015 ABYSS03 0 5 638.433 637.068 0 1
5 1009 OPENWATER02 0 5 319.17 -0.0658667 0 1
6 1009 OPENWATER03 0 5 638.633 -0.399733 0 1
7 1009 OPENWATER04 0 5 319.025 319.734 0 1
8 1009 OPENWATER06 0 5 638.63 317.827 0 1
9 1007 SONGCAVE02 1 2 128.578 159.092 0 0.387867
10 1007 SONGCAVE 1 5 118.842 147.471 0 0.599717
11 1014 VEIL01 0 5 638.579 -639.354 0 1
12 1014 VEIL02 0 5 958.132 -639.401 0 1
13 1009 VEIL03 0 5 638.221 -319.998 0 1
14 1010 FOREST02 0 5 -0.0961994 -639.541 0 1
15 1010 FOREST03 0 5 319.841 -639.163 0 1
16 1010 FOREST04 0 5 -0.0881051 -320.302 0 1
17 1010 FOREST05 0 5 319.692 -320.261 0 1
18 1025 FORESTSPRITECAVE 1 2 295.55 -631.495 0 0.45125
19 1026 FISHCAVE 1 2 -18.0111 -342.826 0 0.51796
20 1013 SUNTEMPLE 1 5 961.345 -687.826 0 0.22643
21 1016 SUNKENCITY01 1 2.5 -40.8617 906.841 0 1
22 1016 SUNKENCITY02 1 5 116.437 802.774 0 1
23 1000 BOILERROOM 1 2 49.228 940.225 0 1
24 1004 ENERGYTEMPLE01 1 2.5 -168.536 -8.8143 0 1
25 1004 ENERGYTEMPLE02 1 0.5 -232.22 -0.657245 0 1
26 1004 ENERGYTEMPLE03 1 2.5 -110.834 56.4481 0 1
27 1004 ENERGYTEMPLE04 1 4 -246.593 145.535 0 1
28 1004 ENERGYTEMPLE05 1 2 -207.873 175.936 0 1
29 1004 ENERGYTEMPLE06 1 2 -225.836 41.8167 0 1
30 1011 MITHALAS01 0 5 958.305 -0.399733 0 1
31 1011 MITHALAS02 1 5 1178.23 40.9613 0 1
32 1012 CATHEDRAL02 1 5 1458.63 70.988 0 1
33 1012 CATHEDRAL03 1 5 1491.23 315.666 0 1
34 1012 CATHEDRAL04 1 5 1231.44 457.454 0 1
35 1029 LICAVE 1 2 796.398 -663.693 0 0.500888
36 1013 SUNWORMTEST 1 4 987.255 -699.643 0 0.213937
37 1010 TREE02 0 2 -11.9703 -830.088 0 1
38 1028 SEAHORSE 1 5 803.549 308.257 0 1
39 1027 TURTLECAVE 1 5 371.817 -730.55 0 1
40 1019 ICECAVE 1 5 917.784 686.531 0 1
41 1002 FROZENVEIL 0 5 1646.98 -590.166 0 1
42 1003 BUBBLECAVE02 1 5 1841.07 -709.693 0 1
43 1024 MERMOGCAVE 1 2 482.591 -781.434 0 1
44 1023 TRAININGCAVE 1 4 247.338 -85.5629 1 1
45 1021 FINAL01 1 5 398.925 949.441 0 1
46 1021 FINAL02 1 5 79.3004 949.894 0 1
47 1021 FINAL03 1 5 718.257 958.177 0 1
48 1021 FINAL04 1 5 402.406 1269.56 0 1
49 1021 FINALBOSS 1 5 667.938 1486.98 0 1
50 1018 OCTOCAVE 1 2 834.888 -606.756 0 0.831527
51 1009 OPENWATER05 0 5 270.156 327.801 0 1.01408
52 1020 THIRTEENLAIR 1 5 417.62 -121.396 0 1
53 1030 KINGJELLYCAVE 1 2 328.989 605.32 0 0.356187
54 1020 WEIRDCAVE 1 0.5 548.557 709.137 0 1
55 1001 WHALE 1 2.52755 505.274 741.664 0 0.526182

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -220,7 +220,10 @@ function postInit(me)
updateLocation(me)
end
-- Both exist. Different spelling. Yay for consistency.
-- Keeping them both, should ensure behavior as it used to be, just without warnings. -- FG
v.incutscene = false
v.inCutScene = false
local function cutsceneintro(me, node)
v.incutscene = true

View file

@ -367,7 +367,7 @@ function update(me, dt)
end
end
if entity_isState(me, STATE_MOVING) and entity_x(me) >= node_x(v.maxMove) then
if entity_isInterpolating() then
if entity_isInterpolating(me) then
entity_animate(me, "idle")
end
entity_stopInterpolating(me)
@ -400,7 +400,7 @@ function enterState(me)
entity_stopInterpolating(me)
entity_animate(me, "idle", LOOP_INF)
elseif entity_isState(me, STATE_ATTACK) then
playSfx("EnergyBoss-Attack", 900+math.random(200))
playSfx("EnergyBoss-Attack", (900+math.random(200)) / 1000)
local x, y = bone_getPosition(v.bone_jaw)
if entity_isPositionInRange(v.naija, x, y, 600)
and entity_y(v.naija) < y+64
@ -441,12 +441,12 @@ function enterState(me)
end
v.attackDelay = 0
v.fireDelay = 0
playSfx("EnergyBoss-Hurt", 900+math.random(200))
playSfx("EnergyBoss-Hurt", (900+math.random(200)) / 1000)
entity_animate(me, "hurt")
entity_setPosition(me, entity_x(me)-500, entity_y(me), 1.6)
elseif entity_isState(me, STATE_HITBARRIER) then
entity_stopInterpolating(me)
playSfx("EnergyBoss-Die", 1100+math.random(200))
playSfx("EnergyBoss-Die", (1100+math.random(200)) / 1000)
entity_animate(me, "hitBarrier")
entity_spawnParticlesFromCollisionMask(me, "energyboss-hit", 4)
@ -459,7 +459,7 @@ function enterState(me)
entity_setPosition(me, node_x(backNode), entity_y(me), -800)
elseif entity_isState(me, STATE_COLLAPSE) then
clearShots()
playSfx("EnergyBoss-Die", 1000)
playSfx("EnergyBoss-Die")
setFlag(FLAG_ENERGYBOSSDEAD, 1)
entity_setDamageTarget(me, DT_AVATAR_ENERGYBLAST, false)
entity_setDamageTarget(me, DT_AVATAR_SHOCK, false)
@ -504,7 +504,7 @@ function enterState(me)
--end
elseif entity_isState(me, STATE_INTRO) then
v.awoken = true
playSfx("EnergyBoss-Die", 800)
playSfx("EnergyBoss-Die", 0.8)
shakeCamera(10, 3)
entity_stopInterpolating(me)
entity_animate(me, "roar")

View file

@ -132,6 +132,7 @@ function update(me, dt)
if entity_hasTarget(me) then
target = entity_getTarget(me)
if target ~= 0 then
--[[
ox, oy = entity_getOffset(target)
cx = entity_x(target) + ox + entity_velx(target)
@ -141,6 +142,7 @@ function update(me, dt)
cx = cx + entity_velx(target)
cy = cy + entity_vely(target)
dist = 40
end
--debugLog(string.format("distTimer: %f", v.distTimer))
v.distTimer = v.distTimer + dt * 0.5
@ -160,8 +162,10 @@ function update(me, dt)
end
end
if target ~= 0 then
entity_flipToEntity(me, target)
entity_rotateToEntity(me, target)
end
local a = t
x = x + math.sin(a)*dist

View file

@ -28,6 +28,7 @@ v.getOutHits = 0
v.hx = 0
v.hy = 0
v.hurtTimer = 0
v.trapDelay = 0
local STATE_TRAP = 1001
local STATE_TRAPPED = 1002

View file

@ -352,10 +352,6 @@
RelativePath="..\..\BBGE\ParticleManager.cpp"
>
</File>
<File
RelativePath="..\..\BBGE\Particles.cpp"
>
</File>
<File
RelativePath="..\..\BBGE\Particles.h"
>

View file

@ -1219,6 +1219,10 @@
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\..\ExternalLibs\algorithmx.h"
>
</File>
<Filter
Name="FTGL"
>