1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-10-04 05:13:19 +00:00

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

This commit is contained in:
fgenesis 2013-06-26 04:23:54 +01:00
commit 632326dbdf
84 changed files with 3010 additions and 4164 deletions

View file

@ -1057,11 +1057,53 @@ void AnimationEditor::applyTranslation()
{
if (editingBone)
{
BoneKeyframe *b = editSprite->getCurrentAnimation()->getKeyframe(currentKey)->getBoneKeyframe(editingBone->boneIdx);
if (b)
if (!core->getShiftState())
{
b->x = editingBone->position.x;
b->y = editingBone->position.y;
// one bone mode
BoneKeyframe *b = editSprite->getCurrentAnimation()->getKeyframe(currentKey)->getBoneKeyframe(editingBone->boneIdx);
if (b)
{
b->x = editingBone->position.x;
b->y = editingBone->position.y;
}
}
else
{
BoneKeyframe *bcur = editSprite->getCurrentAnimation()->getKeyframe(currentKey)->getBoneKeyframe(editingBone->boneIdx);
if (bcur)
{
int xdiff = editingBone->position.x - bcur->x;
int ydiff = editingBone->position.y - bcur->y;
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);
if (b)
{
b->x += xdiff;
b->y += ydiff;
}
}
}
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;
}
}
}
}
}
}
}
}
@ -1149,10 +1191,48 @@ void AnimationEditor::rmbu()
{
if (editingBone)
{
BoneKeyframe *b = editSprite->getCurrentAnimation()->getKeyframe(currentKey)->getBoneKeyframe(editingBone->boneIdx);
if (b)
if (!core->getShiftState())
{
b->rot = int(editingBone->rotation.z);
// one bone mode
BoneKeyframe *b = editSprite->getCurrentAnimation()->getKeyframe(currentKey)->getBoneKeyframe(editingBone->boneIdx);
if (b)
{
b->rot = int(editingBone->rotation.z);
}
}
else
{
BoneKeyframe *bcur = editSprite->getCurrentAnimation()->getKeyframe(currentKey)->getBoneKeyframe(editingBone->boneIdx);
if (bcur)
{
int rotdiff = editingBone->rotation.z - bcur->rot;
if (!core->getCtrlState())
{
for (int i = 0; i < editSprite->getCurrentAnimation()->getNumKeyframes(); ++i)
{
BoneKeyframe *b = editSprite->getCurrentAnimation()->getKeyframe(i)->getBoneKeyframe(editingBone->boneIdx);
if (b)
{
b->rot += rotdiff;
}
}
}
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

@ -12,6 +12,9 @@
#define AQUARIA_CUSTOM_BUILD_ID ""
// If defined, this is shown instead of "Aquaria vx.x.x ..." on the title screen.
//#define AQUARIA_OVERRIDE_VERSION_STRING "Aquaria OSE v1.000"
#endif

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)

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define AVATAR_H
#include "../BBGE/Particles.h"
#include "../BBGE/BitmapFont.h"
#include "DSQ.h"
#include "Hair.h"
@ -30,9 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "Web.h"
class SpringPlant;
//class Item;
class TileVector;
class SongIcon;
@ -70,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:
@ -106,20 +109,10 @@ protected:
void onUpdate(float dt);
};
class FormIcon : public Quad
{
public:
FormIcon();
protected:
bool cursorIsIn;
void onUpdate(float dt);
};
class AvatarState
{
public:
AvatarState();
Timer dodgeEffectTimer;
Timer blindTimer;
float abilityDelay;
bool blind;
@ -127,12 +120,10 @@ public:
float shotDelay;
//Timer shockTimer;
Timer useItemDelay;
Timer tapTimer;
Timer lockToWallDelay;
float spellCharge;
bool lockedToWall;
float leachTimer;
bool crawlingOnWall;
bool nearWall;
float swimTimer, rollTimer;
float updateLookAtTime;
@ -151,23 +142,14 @@ public:
virtual ~Avatar();
void destroy();
void action(int actionID, int state);
// anim data
AnimData anim_swim, anim_stopTransition, anim_idle, anim_idle2, anim_burst, anim_fish;
AvatarState state;
void setIgnoreInputDelay(float delay)
{
ignoreInputDelay = delay;
}
float burst, burstTimer;
float burstDelay;
bool bursting;
BurstType lastBurstType;
//void damage(int amount);
bool isCharging();
void slowToRest();
void debugMsg(const std::string &msg);
void setBlind(float time);
void onBlindTest();
void revive();
@ -185,10 +167,7 @@ public:
Entity *entityToActivate;
Path *pathToActivate;
Entity *lastEntityActivation;
void shift();
void applyWorldEffects(WorldType type);
Vector extraVel;
void toggleMovement(bool on);
@ -223,16 +202,11 @@ public:
void changeForm(FormType form, bool effects=true, bool onInit=false, FormType lastForm=FORM_NONE);
void singNote(int note);
std::vector<SongIcon*> songIcons;
std::vector<FormIcon*> formIcons;
//std::vector<int> currentsong;
Song currentSong;
int currentSongIdx;
Entity *pullTarget;
bool pickingPullTarget;
void openPullTargetInterface();
void closePullTargetInterface();
void setNearestPullTarget();
void formAbility(int ability);
@ -246,16 +220,11 @@ public:
bool canDie;
bool warpIn;
Vector warpInLocal;
float biteDelay, urchinDelay, jellyDelay;
bool movingOn;
int ropeState;
float ropeTimer;
Vector ropePos, ropeVel;
void fireRope();
void render();
void activateAura(AuraType aura);
void stopAura();
@ -267,7 +236,6 @@ public:
void updateFormVisualEffects(float dt);
bool isSinging();
bool isLockable();
float stopTimer;
int getCursorQuadrant();
void onWarp();
int getBurstDistance();
@ -278,16 +246,12 @@ public:
int rollDir;
std::string getBurstAnimName();
std::string getRollAnimName();
void startWallCrawl();
void stopWallCrawl();
void updateDualFormChargeEffects();
TileVector wallLockTile;
Vector wallNormal, lastWallNormal;
Vector wallNormal;
void openFormInterface();
void closeFormInterface();
void fallOffWall();
float fireDelay;
@ -296,8 +260,6 @@ public:
AuraType activeAura;
float auraTimer;
bool fireAtNearestValidEntity(const std::string &shot);
EatType inTummy;
float tummyTimer;
void checkNearWall();
Vector getAim();
@ -309,7 +271,6 @@ public:
void updatePosition();
float quickSongCastDelay;
void onAnimationKeyPassed(int key);
int tummyAmount;
bool isSwimming();
@ -329,6 +290,7 @@ public:
void endOfGameState();
bool canQuickSong();
bool canActivateStuff();
void setCanActivateStuff(bool on);
bool hasThingToActivate();
float biteTimer;
@ -362,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();
@ -372,23 +354,17 @@ protected:
int curWebPoint;
void checkUpgradeForShot(Shot *s);
int getNumShots();
void updateCursorFromKeyboard();
void lockToWallCommon();
void onSetBoneLock();
void onUpdateBoneLock();
InterpolatedVector cursorPos;
void adjustHeadRot();
std::string lastHeadTexture;
void updateDualFormGlow(float dt);
Vector getTendrilAimVector(int i, int max);
void applyRidingPosition();
Vector lastWallJumpPos, lastWallJumpDir;
void stopWallJump();
void updateWallJump(float dt);
int wallJumps;
float wallBurstTimer;
float targetUpdateDelay;
std::vector<Target> targets;
@ -409,11 +385,7 @@ protected:
float fallGravityTimer;
Vector fallGravity;
int lastOutOfWaterMaxSpeed;
void spawnSeed();
int shieldPoints;
bool inFormInterface;
void onIdle();
void onHeal(int type);
ParticleEffect biteLeftEmitter, biteRightEmitter, swimEmitter, auraHitEmitter;
@ -422,7 +394,6 @@ protected:
ParticleEffect *leftHandEmitter, *rightHandEmitter;
ParticleEffect *chargingEmitter, *chargeEmitter;
void updateCursor(float dt);
float canWarpDelay;
bool rolling;
int rollDidOne;
@ -430,19 +401,12 @@ protected:
void stopRoll();
int getQuadrantDirection(int lastQuad, int quad);
void updateRoll(float dt);
void updateTummy(float dt);
int lastQuad, lastQuadDir;
void onDamage(DamageData &d);
void updateHair(float dt);
void lostTarget(int i, Entity *e);
float doubleClickDelay;
float damageDelay;
bool didShockDamage;
void updateShock(float dt);
float shockTimer;
Vector shieldPosition;
void updateAura(float dt);
@ -458,15 +422,12 @@ protected:
void clampVelocity();
bool canCharge(int ability);
int abilityCharging;
void formAbilityUpdate(float dt);
Entity *potentialPullTarget;
float revertTimer;
void endCharge();
Entity *activateEntity;
bool canMove;
float castShockTimer;
void onEnterState(int action);
void onExitState(int action);
@ -475,28 +436,17 @@ protected:
void applyBlindEffects();
void removeBlindEffects();
//bool blind;
bool animatedBurst;
float zoomVel;
// implement "bobbing" in a lower class
int getBeamWidth();
Vector getWallNormal(TileVector t);
void onToggleDebugMessages();
float spellCastDelay;
float spellChargeMin;
bool checkWarpAreas();
void checkSpecial();
void toggleZoom();
float ignoreInputDelay;
float idleAnimDelay;
float splashDelay;
//Hair *hair;
BitmapText *text;
//Item *currentItem;
void onUpdate(float dt);
void onRender();
@ -506,42 +456,34 @@ protected:
Quad *glow;
bool swimming;
void doRangePush(float dt);
void doRangePull(float dt);
void lmbd();
void lmbu();
void rmbd();
void rmbd2();
void rmbu();
bool charging;
AnimData tongueAnim;
//Quad *chargeGraphic;
Vector lastPush;
std::string tapped;
float dodgeDelay;
float pushingOffWallEffect;
float lockToWallFallTimer;
void dodge(std::string dir);
void doDodgeInput(const std::string &action, int state);
Vector dodgeVec;
Vector wallPushVec, wallTurnVec;
Vector lastLockToWallPos;
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,22 +70,23 @@ 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)
{
learnRecipe(d->name, effects);
if(learn)
learnRecipe(d->name, effects);
if (!getIngredientHeldByName(d->name))
{
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;
}
}
@ -590,6 +591,14 @@ std::string Continuity::getIEString(IngredientData *data, int i)
case IET_LI:
return dsq->continuity.stringBank.get(227);
break;
case IET_SCRIPT:
if(dsq->game->cookingScript)
{
std::string ret = "";
dsq->game->cookingScript->call("getIngredientEffectString", data->name.c_str(), &ret);
return ret;
}
break;
}
return "";
@ -607,8 +616,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,29 +852,28 @@ 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++)
{
str += splitCamelCase(getIngredientDescription(data->effects[i].type)) + "\n";
}
return str;
*/
return getAllIEString(data);
}
@ -910,6 +920,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 +967,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 +979,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 +1085,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 +1109,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 +1429,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;
@ -1392,6 +1464,10 @@ void Continuity::castSong(int num)
effect->setPositionSnapTo(&dsq->game->avatar->position);
dsq->game->addRenderObject(effect, LR_PARTICLES);
// song->script == 0: internal handler only
// song->script == 1: script handler only
// song->script == 2: both
if (song->script)
{
if (dsq->mod.isActive())
@ -1399,37 +1475,16 @@ void Continuity::castSong(int num)
else
dsq->runScriptNum("songs.lua", "castSong", num);
}
else
if (song->script != 1)
{
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);
@ -1943,9 +1998,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;
@ -2331,15 +2392,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);
@ -2436,6 +2516,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);
@ -2454,6 +2535,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++)
{
@ -2487,6 +2578,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);
@ -2526,6 +2685,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;
@ -2563,7 +2725,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
@ -2709,6 +2871,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");
@ -2746,6 +2909,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());
@ -2785,7 +2996,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;
}
@ -2828,7 +3041,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;
@ -2893,7 +3122,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;
@ -2906,6 +3135,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"));
@ -2916,9 +3160,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);
}
}
}
@ -2997,40 +3356,6 @@ int Continuity::getPathFlag(Path *p)
return entityFlags[os2.str()];
}
SporeChildData *Continuity::getSporeChildDataForEntity(Entity *e)
{
SporeChildData *scd=0;
for (int i = 0; i < sporeChildData.size(); i++)
{
if (sporeChildData[i].entity == e)
{
scd = &sporeChildData[i];
break;
}
}
return scd;
}
void Continuity::registerSporeChildData(Entity *e)
{
if (!dsq->game->creatingSporeChildren)
{
SporeChildData *scd=0;
if (!(scd = getSporeChildDataForEntity(e)))
{
SporeChildData d;
sporeChildData.push_back(d);
scd = &sporeChildData[sporeChildData.size()-1];
}
if (scd)
{
scd->state = e->getState();
scd->health = e->health;
scd->entity = e;
}
}
}
class GemGet : public Quad
{
public:
@ -3108,6 +3433,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
@ -3218,6 +3544,7 @@ void Continuity::reset()
//worldMapTiles.clear();
speedMult = biteMult = fishPoison = defenseMult = 1;
speedMult2 = 1;
poison = 0;
energyMult = 0;
light = petPower = 0;
@ -3247,45 +3574,15 @@ 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();
formUpgrades.clear();
sporeChildData.clear();
auraType = AURA_NONE;
for (int i = 0; i < MAX_FLAGS; i++)

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

@ -153,7 +153,8 @@ Vector savesz;
#define APPNAME "Aquaria"
#endif
DSQ::DSQ(std::string fileSystem) : Core(fileSystem, LR_MAX, APPNAME, PARTICLE_AMOUNT_DEFAULT, "Aquaria")
DSQ::DSQ(const std::string& fileSystem, const std::string& extraDataDir)
: Core(fileSystem, extraDataDir, LR_MAX, APPNAME, PARTICLE_AMOUNT_DEFAULT, "Aquaria")
{
// 2048
//createDirectory(getSaveDirectory());
@ -198,8 +199,6 @@ DSQ::DSQ(std::string fileSystem) : Core(fileSystem, LR_MAX, APPNAME, PARTICLE_AM
menuSelectDelay = 0;
modSelectorScr = 0;
blackout = 0;
useMic = false;
autoSingMenuOpen = false;
inputMode = INPUT_MOUSE;
overlay = 0;
recentSaveSlot = -1;
@ -616,6 +615,7 @@ void DSQ::debugMenu()
core->afterEffectManager->loadShaders();
}
dsq->user.load();
dsq->continuity.loadIngredientData();
}
else if (c == '2')
{
@ -844,7 +844,13 @@ void loadBitForTexPrecache()
}
void DSQ::setVersionLabelText() {
void DSQ::setVersionLabelText()
{
#ifdef AQUARIA_OVERRIDE_VERSION_STRING
versionLabel->setText(AQUARIA_OVERRIDE_VERSION_STRING);
return;
#endif
std::ostringstream os;
os << "Aquaria";
@ -923,12 +929,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;
@ -998,8 +1006,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);
@ -1042,7 +1049,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;
}
@ -1534,10 +1541,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);
@ -2156,7 +2163,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);
@ -2336,6 +2342,8 @@ void DSQ::playPositionalSfx(const std::string &name, const Vector &position, flo
void DSQ::shutdown()
{
mod.stop();
Network::shutdown();
scriptInterface.shutdown();
@ -4492,7 +4500,7 @@ void DSQ::onUpdate(float dt)
dsq->setInputMode(INPUT_MOUSE);
}
if (isDeveloperKeys())
/*if (isDeveloperKeys())
{
if (core->getCtrlState())
{
@ -4505,7 +4513,7 @@ void DSQ::onUpdate(float dt)
if (core->getKeyState(KEY_DOWN))
core->adjustWindowPosition(0, 5);
}
}
}*/
if (isDeveloperKeys() && cmDebug && cmDebug->alpha == 1 && fpsText)
{
@ -4534,8 +4542,7 @@ void DSQ::onUpdate(float dt)
os << "maxSpeed: " << dsq->game->avatar->currentMaxSpeed << " - ";
os << "lockedToWall: " << dsq->game->avatar->state.lockedToWall;
os << std::endl;
os << "crwlng: " << avatar->state.crawlingOnWall;
os << " swmng: " << avatar->isSwimming();
os << "swmng: " << avatar->isSwimming();
os << " dualFormCharge: " << continuity.dualFormCharge;
os << std::endl;
os << "vel(" << avatar->vel.x << ", " << avatar->vel.y << ") ";
@ -4544,9 +4551,8 @@ void DSQ::onUpdate(float dt)
os << "rot: " << avatar->rotation.z << " rotoff: " << avatar->rotationOffset.z << std::endl;
os << "p(" << int(avatar->position.x) << ", " << int(avatar->position.y) << ")" << std::endl;
os << "inp: " << avatar->isInputEnabled() << std::endl;
os << "wallNormal(" << avatar->wallNormal.x << ", " << avatar->wallNormal.y << ")" << std::endl;
os << "wallNormal(" << avatar->wallNormal.x << ", " << avatar->wallNormal.y << ") collradius: " << avatar->collideRadius << std::endl;
os << "burst: " << avatar->burst << " burstTimer: " << avatar->burstTimer << std::endl;
os << "inTummy: " << avatar->inTummy << " tummyAmount: " << avatar->tummyAmount << std::endl;
os << "inCurrent: " << avatar->isInCurrent() << std::endl;
os << "qsongCastDelay: " << avatar->quickSongCastDelay << std::endl;
os << "singing: " << dsq->game->avatar->singing << " blockSinging: " << dsq->game->avatar->isBlockSinging();
@ -4568,6 +4574,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
@ -4580,6 +4590,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);
@ -4594,7 +4605,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();
@ -4669,6 +4680,8 @@ void DSQ::onUpdate(float dt)
lockMouse();
Network::update();
Shot::clearShotGarbage();
}
void DSQ::lockMouse()
@ -5120,16 +5133,9 @@ void DSQ::cutsceneEffects(bool on)
}
}
void pauseSound()
void DSQ::onBackgroundUpdate()
{
if (dsq && dsq->sound) {
dsq->sound->pause();
}
Network::update();
Core::onBackgroundUpdate();
}
void resumeSound()
{
if (dsq && dsq->sound) {
dsq->sound->resume();
}
}

View file

@ -122,6 +122,7 @@ enum AquariaActions
ACTION_ROLL,
ACTION_SLOW, // currently unused
ACTION_REVERT,
ACTION_ZOOMIN = 200,
ACTION_ZOOMOUT,
@ -256,6 +257,7 @@ class Mod
{
public:
Mod();
~Mod();
void clear();
void setActive(bool v);
void start();
@ -296,6 +298,7 @@ protected:
std::string name;
std::string path;
Precacher modcache;
};
class AquariaScreenTransition : public ScreenTransition
@ -311,7 +314,7 @@ struct Song
Song() { index=0; script=0; }
int index;
SongNotes notes;
bool script;
int script;
};
const int MAX_FLAGS = 1024;
@ -615,6 +618,7 @@ struct GemData
GemData() { canMove=false; }
std::string name;
std::string userString;
std::string mapName;
bool canMove;
Vector pos;
};
@ -682,6 +686,7 @@ enum IngredientEffectType
IET_POISON = 17,
IET_BLIND = 18,
IET_ALLSTATUS = 19,
IET_SCRIPT = 20,
IET_MAX
};
@ -712,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;
@ -826,28 +833,6 @@ public:
void load();
};
enum CMStat
{
CM_ID =0,
CM_EGO,
CM_SEGO
};
class WordColoring
{
public:
std::string word;
Vector color;
};
struct SporeChildData
{
SporeChildData() : state(0), entity(0), health(0) {}
int state;
int health;
Entity *entity;
};
const int FLAG_LI = 1000, FLAG_LICOMBAT = 1001;
const int FLAG_COOKS = 21;
@ -966,7 +951,7 @@ public:
std::string getSaveFileName(int slot, const std::string &pfix);
int maxHealth;
float maxHealth;
float health;
bool hudVisible;
unsigned int exp;
@ -1008,8 +993,6 @@ public:
std::string naijaModel;
std::vector<WordColoring> wordColoring;
FormType form;
void learnFormUpgrade(FormUpgradeType form);
@ -1019,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);
@ -1065,12 +1047,6 @@ public:
AuraType auraType;
float auraTimer;
SporeChildData *getSporeChildDataForEntity(Entity *e);
void registerSporeChildData(Entity *e);
std::vector<SporeChildData> sporeChildData;
EatData *getEatData(const std::string &name);
void loadEatBank();
@ -1079,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
@ -1087,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(); }
@ -1127,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();
@ -1256,7 +1235,7 @@ enum NagType
class DSQ : public Core
{
public:
DSQ(std::string fileSystem);
DSQ(const std::string& fileSystem, const std::string& extraDataDir);
~DSQ();
void init();
@ -1452,7 +1431,6 @@ public:
void rumble(float leftMotor, float rightMotor, float time);
void vision(std::string folder, int num, bool ignoreMusic = false);
bool useMic, autoSingMenuOpen;
void watch(float t, int canQuit = 0);
std::string lastVoiceFile;
@ -1585,6 +1563,9 @@ public:
void pauseCutscene(bool on);
bool canSkipCutscene();
bool isSkippingCutscene();
virtual void onBackgroundUpdate();
protected:
Quad *cutscene_bg;

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()
{
@ -217,7 +217,6 @@ Entity::Entity()
targetRange = 32;
//energyChargeTarget = energyShotTarget = true;
deathSound = "GenericDeath";
groupID = 0;
entityID = 0;
//assignUniqueID();
hair = 0;
@ -349,50 +348,6 @@ void Entity::setSpiritFreeze(bool v)
spiritFreeze = v;
}
Vector Entity::getGroupCenter()
{
Vector position;
int sz = 0;
FOR_ENTITIES(i)
{
Entity *e = *i;
if (e->getGroupID() == this->getGroupID())
{
position += e->position;
sz++;
}
}
position/=sz;
return position;
}
Vector Entity::getGroupHeading()
{
Vector v;
int sz = 0;
FOR_ENTITIES(i)
{
Entity *e = *i;
if (e->getGroupID() == this->getGroupID())
{
v += e->vel;
sz++;
}
}
v/=sz;
return v;
}
int Entity::getGroupID()
{
return groupID;
}
void Entity::setGroupID(int g)
{
groupID = g;
}
void Entity::setEntityProperty(EntityProperty ep, bool value)
{
entityProperties[int(ep)] = value;
@ -501,9 +456,9 @@ void Entity::followPath(Path *p, int speedType, int dir, bool deleteOnEnd)
position.data->path.addPathNode(pn.position, float(i/float(p->nodes.size())));
}
}
debugLog("Calculating Time");
//debugLog("Calculating Time");
float time = position.data->path.getLength()/(float)dsq->continuity.getSpeedType(speedType);
debugLog("Starting");
//debugLog("Starting");
position.data->path.getPathNode(0)->value = position;
position.startPath(time);//, 1.0f/2.0f);
}
@ -574,37 +529,6 @@ void Entity::moveToNode(Path *path, int speedType, int dieOnPathEnd, bool swim)
//position.startPath(((position.data->path.getNumPathNodes()*TILE_SIZE*4)-2)/dsq->continuity.getSpeedType(speedType));
}
void Entity::addNodeToNodeGroup(int group, Path *p)
{
nodeGroups[group].push_back(p);
}
void Entity::removeNodeFromAllNodeGroups(Path *p)
{
for (int j = 0; j < nodeGroups.size(); j++)
{
for (int i = 0; i < nodeGroups[j].size(); i++)
{
if (nodeGroups[j][i] == p)
{
nodeGroups[j][i] = 0;
}
}
}
}
void Entity::setNodeGroupActive(int group, bool v)
{
for (int i = 0; i < nodeGroups[group].size(); i++)
{
Path *p = nodeGroups[group][i];
if (p)
{
p->setActive(v);
}
}
}
void Entity::stopFollowingPath()
{
position.stopPath();
@ -627,39 +551,6 @@ void Entity::flipToTarget(Vector pos)
}
}
bool Entity::isCollideAgainst(Entity *e)
{
if (this == e) return false;
if (getEntityType()==ET_PET || getEntityType()==ET_AVATAR || getEntityType() == ET_NEUTRAL)
{
if (e->getEntityType()==ET_ENEMY || e->getEntityType()==ET_NEUTRAL)
{
return true;
}
}
if (getEntityType() == ET_ENEMY)
{
if (e->getEntityType()==ET_PET || e->getEntityType()==ET_AVATAR || e->getEntityType()==ET_NEUTRAL)
return true;
}
return false;
}
bool Entity::isOpposedTo(Entity *e)
{
if (getEntityType()==ET_PET || getEntityType()==ET_AVATAR || getEntityType() == ET_NEUTRAL)
{
if (e->getEntityType()==ET_ENEMY || e->getEntityType()==ET_NEUTRAL)
return true;
}
if (getEntityType() == ET_ENEMY)
{
if (e->getEntityType()==ET_PET || e->getEntityType()==ET_AVATAR)
return true;
}
return false;
}
Entity* Entity::getTargetEntity(int t)
{
return targets[t];
@ -921,7 +812,7 @@ void Entity::heal(float a, int type)
}
}
void Entity::revive(int a)
void Entity::revive(float a)
{
entityDead = false;
health = 0;
@ -1189,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;
}
@ -1214,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;
}
@ -1251,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;
@ -1266,7 +1157,7 @@ void Entity::update(float dt)
//skeletalSprite.setFreeze(true);
if (frozenTimer == 0 || getState() == STATE_PUSH)
AnimatedSprite::update(dt);
Quad::update(dt);
onAlwaysUpdate(dt);
// always, always update:
@ -1491,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)
{
@ -1528,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);
}
@ -1548,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())
@ -1755,7 +1646,8 @@ void Entity::setPoison(float m, float t)
{
poison = m;
poisonTimer.start(t);
poisonBitTimer.start(dsq->continuity.poisonBitTime);
if (poison)
poisonBitTimer.start(dsq->continuity.poisonBitTime);
}
void Entity::onUpdate(float dt)
@ -1789,7 +1681,7 @@ void Entity::onUpdate(float dt)
break;
}
blurShaderAnim.update(dt);
//blurShaderAnim.update(dt);
}
@ -1873,7 +1765,7 @@ void Entity::onUpdate(float dt)
}
}
AnimatedSprite::onUpdate(dt);
Quad::onUpdate(dt);
Vector v = position - lastPos;
lastMove = v;
@ -2458,24 +2350,6 @@ void Entity::moveTowardsTarget(float dt, int spd, int t)
moveTowards(targets[t]->position, dt, spd);
}
void Entity::moveTowardsGroupCenter(float dt, int speed)
{
if (getGroupID() != 0)
{
moveTowards(getGroupCenter(), dt, speed);
}
}
void Entity::moveTowardsGroupHeading(float dt, int speed)
{
if (getGroupID() != 0)
{
Vector d = getGroupHeading() - position;
d.setLength2D(speed*dt);
vel += d;
}
}
void Entity::moveAroundTarget(float dt, int spd, int dir, int t)
{
if (!targets[t]) return;
@ -2914,7 +2788,7 @@ void Entity::doEntityAvoidance(float dt, int range, float mod, Entity *ignore)
{
Entity *e = *i;
if (e != this && e != ignore && e->ridingOnEntity != this)
if (e != this && e != ignore && e->ridingOnEntity != this && !e->getv(EV_NOAVOID))
{
diff = (this->position - e->position);
if (diff.isLength2DIn(range) && !diff.isZero())
@ -2958,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;
}
AnimatedSprite::render();
}*/
Quad::render();
//if (beautyFlip && blurShader.isLoaded() && flipScale.isInterpolating())
if (set)
blurShader.unbind();
//if (set)
// blurShader.unbind();
renderBorder = false;
skeletalSprite.clearColorMult();
color = bcolor;
@ -3038,7 +2907,7 @@ void Entity::doSpellAvoidance(float dt, int range, float mod)
{
Shot *s = (Shot*)(*i);
if ((s->position - this->position).getSquaredLength2D() < sqr(range))
if (s->isActive() && (s->position - this->position).getSquaredLength2D() < sqr(range))
{
for (int j = 0; j < ignoreShotDamageTypes.size(); j++)
{
@ -3223,3 +3092,50 @@ bool Entity::doCollisionAvoidance(float dt, int search, float mod, Vector *vp, i
return false;
}
void Entity::initHair(int numSegments, int segmentLength, int width, const std::string &tex)
{
if (hair)
{
errorLog("Trying to init hair when hair is already present");
}
hair = new Hair(numSegments, segmentLength, width);
hair->setTexture(tex);
dsq->game->addRenderObject(hair, layer);
}
void Entity::setHairHeadPosition(const Vector &pos)
{
if (hair)
{
hair->setHeadPosition(pos);
}
}
void Entity::updateHair(float dt)
{
if (hair)
{
hair->updatePositions();
}
}
void Entity::exertHairForce(const Vector &force, float dt)
{
if (hair)
{
hair->exertForce(force, 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

@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef ENTITY_H
#define ENTITY_H
#include "../BBGE/AnimatedSprite.h"
#include "../BBGE/StateMachine.h"
#include "../ExternalLibs/tinyxml.h"
#include "../BBGE/SkeletalSprite.h"
@ -71,7 +70,8 @@ enum EV
EV_MINIMAP = 19, // should the entity show up on the minimap?
EV_SOULSCREAMRADIUS = 20, // 0-n: size of radius for naija's dual form scream attack, -1: always hit
EV_WEBSLOW = 21, // 100 by default, multiplied by dt and then divided into vel
EV_MAX = 22
EV_NOAVOID = 22, // if 1: doEntityAvoidance() will ignore this entity
EV_MAX = 23
};
enum DamageType
@ -123,6 +123,7 @@ enum DamageType
DT_CRUSH = 1032,
DT_SPIKES = 1033,
DT_STEAM = 1034,
DT_WALLHURT = 1035,
DT_REALMAX
};
@ -195,7 +196,7 @@ enum BounceType
BOUNCE_REAL = 1
};
class Entity : public AnimatedSprite, public StateMachine
class Entity : public Quad, public StateMachine
{
public:
Entity();
@ -342,8 +343,6 @@ public:
void setEntityType(EntityType et);
EntityType getEntityType();
bool isOpposedTo(Entity *e);
bool isCollideAgainst(Entity *e);
void flipToTarget(Vector pos);
bool isFollowingPath();
void stopFollowingPath();
@ -354,7 +353,7 @@ public:
bool isHit();
bool pathBurst(bool wallJump = false);
Timer burstTimer;
void revive(int a);
void revive(float a);
void setName(const std::string &name);
void doFriction(float dt);
void doFriction(float dt, int len);
@ -391,10 +390,6 @@ public:
InterpolatedVector maxSpeedLerp;
Hair *hair;
void setGroupID(int gid);
int getGroupID();
Vector getGroupCenter();
Vector getGroupHeading();
void assignUniqueID();
int entityID;
@ -423,12 +418,6 @@ public:
bool isCrawling() { return crawling; }
*/
void flipToVel();
typedef std::vector<Path*> NodeGroup;
typedef std::map<int, NodeGroup> NodeGroups;
NodeGroups nodeGroups;
void addNodeToNodeGroup(int group, Path *p);
void setNodeGroupActive(int group, bool v);
void removeNodeFromAllNodeGroups(Path *p);
bool isInCurrent() { return inCurrent; }
void clearTargetPoints();
void addTargetPoint(const Vector &point);
@ -448,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));
@ -462,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();
@ -491,9 +481,17 @@ public:
void setRidingData(const Vector &pos, float rot, bool fh);
bool isGoingToBeEaten();
void setPoison(float m, float t);
inline float getPoison() const { return poison; }
virtual bool canSetBoneLock();
void initHair(int numSegments, int segmentLength, int width, const std::string &tex);
void updateHair(float dt);
void setHairHeadPosition(const Vector &pos);
void exertHairForce(const Vector &force, float dt);
bool isEntityInside();
protected:
bool calledEntityDied;
Path *waterBubble;
@ -520,7 +518,7 @@ protected:
int lance;
Bone *lanceBone;
void updateLance(float dt);
InterpolatedVector blurShaderAnim;
//InterpolatedVector blurShaderAnim;
int fhScale, fvScale;
@ -545,7 +543,6 @@ protected:
//Vector backupPos, backupVel;
virtual void onIdle() {}
int groupID;
virtual void onHeal(int type){}
virtual void onDamage(DamageData &d){}
virtual void onHealthChange(float change){}
@ -592,7 +589,7 @@ protected:
void updateBoneLock();
int pushMaxSpeed;
std::string currentAnim;
protected:

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;
@ -456,10 +456,13 @@ void FoodSlot::eatMe()
if (!ingredient->effects.empty())
{
ingredient->amount--;
dsq->continuity.applyIngredientEffects(ingredient);
dsq->continuity.removeEmptyIngredients();
dsq->game->refreshFoodSlots(true);
bool eaten = dsq->continuity.applyIngredientEffects(ingredient);
if(eaten)
{
ingredient->amount--;
dsq->continuity.removeEmptyIngredients();
dsq->game->refreshFoodSlots(true);
}
}
else
{
@ -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
@ -819,7 +817,7 @@ void TreasureSlot::onUpdate(float dt)
{
doubleClickTimer = 0;
dsq->runScriptNum("scripts/global/menu-treasures.lua", "useTreasure", flag);
dsq->game->onUseTreasure(flag);
}
else
{
@ -1233,6 +1231,10 @@ Game::Game() : StateObject()
loadEntityTypeList();
lastCollideMaskIndex = -1;
worldPaused = false;
cookingScript = 0;
}
@ -1867,18 +1869,6 @@ void Game::transitionToScene(std::string scene)
core->enqueueJumpState("Game", false);
}
void Game::transitionToSceneUnder(std::string scene)
{
if (avatar)
{
avatar->onWarp();
}
sceneToLoad = scene;
stringToLower(sceneToLoad);
core->pushState("Game");
}
ElementTemplate *Game::getElementTemplateByIdx(int idx)
{
for (int i = 0; i < elementTemplates.size(); i++)
@ -2442,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))
{
@ -2532,7 +2521,7 @@ int Game::getIdxForEntityType(std::string type)
return -1;
}
Entity *Game::createEntity(int idx, int id, Vector position, int rot, bool createSaveData, std::string name, EntityType et, Entity::NodeGroups *nodeGroups, int gid, bool doPostInit)
Entity *Game::createEntity(int idx, int id, Vector position, int rot, bool createSaveData, std::string name, EntityType et, bool doPostInit)
{
std::string type;
for (int i = 0; i < dsq->game->entityTypeList.size(); i++)
@ -2541,7 +2530,7 @@ Entity *Game::createEntity(int idx, int id, Vector position, int rot, bool creat
if (ec->idx == idx)
{
type = ec->name;
return createEntity(type, id, position, rot, createSaveData, name, et, nodeGroups, gid, doPostInit);
return createEntity(type, id, position, rot, createSaveData, name, et, doPostInit);
}
}
return 0;
@ -2580,7 +2569,7 @@ void Game::ensureLimit(Entity *e, int num, int state)
}
}
Entity* Game::establishEntity(Entity *e, int id, Vector position, int rot, bool createSaveData, std::string name, EntityType et, Entity::NodeGroups *nodeGroups, int gid, bool doPostInit)
Entity* Game::establishEntity(Entity *e, int id, Vector position, int rot, bool createSaveData, std::string name, EntityType et, bool doPostInit)
{
// e->layer must be set BEFORE calling this function!
@ -2615,12 +2604,6 @@ Entity* Game::establishEntity(Entity *e, int id, Vector position, int rot, bool
}
}
// get node groups before calling init
if (nodeGroups)
{
e->nodeGroups = (*nodeGroups);
}
// NOTE: init cannot be called after "addRenderObject" for some unknown reason
e->init();
@ -2629,8 +2612,6 @@ Entity* Game::establishEntity(Entity *e, int id, Vector position, int rot, bool
if (!name.empty())
e->name = name;
e->setGroupID(gid);
e->rotation.z = rot;
int idx = getIdxForEntityType(type);
@ -2640,7 +2621,7 @@ Entity* Game::establishEntity(Entity *e, int id, Vector position, int rot, bool
if (createSaveData)
{
int idx = dsq->game->getIdxForEntityType(type);
entitySaveData.push_back(EntitySaveData(e, idx, usePos.x, usePos.y, rot, e->getGroupID(), e->getID(), e->name));
entitySaveData.push_back(EntitySaveData(e, idx, usePos.x, usePos.y, rot, e->getID(), e->name));
}
addRenderObject(e, e->layer);
@ -2653,7 +2634,7 @@ Entity* Game::establishEntity(Entity *e, int id, Vector position, int rot, bool
return e;
}
Entity *Game::createEntity(const std::string &t, int id, Vector position, int rot, bool createSaveData, std::string name, EntityType et, Entity::NodeGroups *nodeGroups, int gid, bool doPostInit)
Entity *Game::createEntity(const std::string &t, int id, Vector position, int rot, bool createSaveData, std::string name, EntityType et, bool doPostInit)
{
std::string type = t;
stringToLower(type);
@ -2663,7 +2644,7 @@ Entity *Game::createEntity(const std::string &t, int id, Vector position, int ro
e = new ScriptedEntity(type, position, et);
return establishEntity(e, id, position, rot, createSaveData, name, et, nodeGroups, gid, doPostInit);
return establishEntity(e, id, position, rot, createSaveData, name, et, doPostInit);
}
void Game::initEntities()
@ -2714,34 +2695,6 @@ EntitySaveData *Game::getEntitySaveDataForEntity(Entity *e, Vector pos)
return 0;
}
void Game::spawnSporeChildren()
{
creatingSporeChildren = true;
SporeChildData *scd;
int sz = dsq->continuity.sporeChildData.size();
for (int i=0; i < sz; i++)
{
scd = &dsq->continuity.sporeChildData[i];
scd->entity = 0;
}
int c = 0;
for (int i=0; i < sz; i++)
{
scd = &dsq->continuity.sporeChildData[i];
Entity *e = dsq->game->createEntity("SporeChild", 0, avatar->position+Vector(0,2+c*2), 0, 0, "");
if (e)
{
e->setState(scd->state);
if (scd->health < 1)
scd->health = 1;
e->health = scd->health;
scd->entity = e;
}
c++;
}
creatingSporeChildren = false;
}
void Game::setTimerTextAlpha(float a, float t)
{
timerText->alpha.interpolateTo(a, t);
@ -4146,8 +4099,7 @@ void Game::toggleOverrideZoom(bool on)
if (!on && avatar->zoomOverriden == true)
{
dsq->globalScale.stop();
dsq->game->avatar->myZoom = dsq->globalScale;
//dsq->game->avatar->myZoom.interpolateTo(Vector(1,1), 1.0);
avatar->myZoom = dsq->globalScale;
}
avatar->zoomOverriden = on;
}
@ -5109,110 +5061,11 @@ bool Game::loadSceneXML(std::string scene)
TiXmlElement *entitiesNode = doc.FirstChildElement("Entities");
while(entitiesNode)
{
if (entitiesNode->Attribute("d"))
{
SimpleIStringStream is(entitiesNode->Attribute("d"));
int idx, x, y;
while (is >> idx)
{
is >> x >> y;
dsq->game->createEntity(idx, 0, Vector(x,y), 0, true, "");
}
}
if (entitiesNode->Attribute("e"))
{
SimpleIStringStream is(entitiesNode->Attribute("e"));
int idx, x, y, rot;
while (is >> idx)
{
is >> x >> y >> rot;
if (idx == 32)
{
std::ostringstream os;
os << "read in rot as: " << rot;
debugLog(os.str());
}
dsq->game->createEntity(idx, 0, Vector(x,y), rot, true, "");
}
}
if (entitiesNode->Attribute("f"))
{
SimpleIStringStream is(entitiesNode->Attribute("f"));
int idx, x, y, rot, group;
while (is >> idx)
{
is >> x >> y >> rot >> group;
Entity *e = dsq->game->createEntity(idx, 0, Vector(x,y), rot, true, "");
e->setGroupID(group);
}
}
if (entitiesNode->Attribute("g"))
{
SimpleIStringStream is(entitiesNode->Attribute("g"));
int idx, x, y, rot, group, id;
while (is >> idx)
{
is >> x >> y >> rot >> group >> id;
Entity *e = dsq->game->createEntity(idx, id, Vector(x,y), rot, true, "");
e->setGroupID(group);
}
}
if (entitiesNode->Attribute("h"))
{
SimpleIStringStream is(entitiesNode->Attribute("h"));
int idx, x, y, rot, groupID, id;
Entity::NodeGroups *ng;
Entity::NodeGroups nodeGroups;
while (is >> idx)
{
int numNodeGroups = 0;
is >> x >> y >> rot >> groupID >> id;
is >> numNodeGroups;
ng = 0;
nodeGroups.clear();
if (numNodeGroups > 0)
{
ng = &nodeGroups;
for (int i = 0; i < numNodeGroups; i++)
{
int sz;
is >> sz;
for (int j = 0; j < sz; j++)
{
int idx;
is >> idx;
if (idx >= 0 && idx < getNumPaths())
{
nodeGroups[i].push_back(getPath(idx));
}
}
}
}
dsq->game->createEntity(idx, id, Vector(x,y), rot, true, "", ET_ENEMY, ng, groupID);
// setting group ID
}
}
if (entitiesNode->Attribute("i"))
{
SimpleIStringStream is(entitiesNode->Attribute("i"));
int idx, x, y, rot, groupID, id;
Entity::NodeGroups nodeGroups;
while (is >> idx)
{
is >> x >> y >> rot >> groupID >> id;
dsq->game->createEntity(idx, id, Vector(x,y), rot, true, "", ET_ENEMY, 0, groupID);
// setting group ID
}
}
if (entitiesNode->Attribute("j"))
{
SimpleIStringStream is(entitiesNode->Attribute("j"));
int idx, x, y, rot, groupID, id;
std::string name;
Entity::NodeGroups nodeGroups;
while (is >> idx)
{
name="";
@ -5221,10 +5074,9 @@ bool Game::loadSceneXML(std::string scene)
is >> x >> y >> rot >> groupID >> id;
if (!name.empty())
dsq->game->createEntity(name, id, Vector(x,y), rot, true, "", ET_ENEMY, 0, groupID);
dsq->game->createEntity(name, id, Vector(x,y), rot, true, "", ET_ENEMY);
else
dsq->game->createEntity(idx, id, Vector(x,y), rot, true, "", ET_ENEMY, 0, groupID);
// setting group ID
dsq->game->createEntity(idx, id, Vector(x,y), rot, true, "", ET_ENEMY);
}
}
entitiesNode = entitiesNode->NextSiblingElement("Entities");
@ -5341,22 +5193,6 @@ void Game::setWarpAreaSceneName(WarpArea &warpArea)
}
}
Entity *Game::getEntityInGroup(int gid, int iter)
{
int c = 0;
FOR_ENTITIES(i)
{
Entity *e = *i;
if (e->getGroupID() == gid)
{
if (iter == c)
return e;
c++;
}
}
return 0;
}
bool Game::loadScene(std::string scene)
{
stringToLower(scene);
@ -5376,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
@ -5552,8 +5388,8 @@ bool Game::saveScene(std::string scene)
else
os << "INVALID" << " ";
}
os << e->x << " " << e->y << " " << e->rot << " " << e->group << " " << e->id << " ";
// group ID no longer used
os << e->x << " " << e->y << " " << e->rot << " " << 0 << " " << e->id << " ";
}
entitiesNode.SetAttribute("j", os.str());
saveFile.InsertEndChild(entitiesNode);
@ -5882,7 +5718,7 @@ void Game::updateParticlePause()
{
core->particlesPaused = 2;
}
else if (dsq->continuity.getWorldType() == WT_SPIRIT)
else if (this->isWorldPaused())
{
core->particlesPaused = 1;
}
@ -5892,46 +5728,6 @@ void Game::updateParticlePause()
}
}
void Game::warpKey1()
{
if (core->getCtrlState())
{
dsq->game->avatar->heal(1000);
dsq->game->avatar->fhTo(true);
warpToSceneNode("OPENWATER02", "WARPKEY");
}
}
void Game::warpKey2()
{
if (core->getCtrlState())
{
dsq->game->avatar->heal(1000);
dsq->game->avatar->fhTo(true);
warpToSceneNode("VEIL01", "WARPKEY");
}
}
void Game::warpKey3()
{
if (core->getCtrlState())
{
dsq->game->avatar->heal(1000);
dsq->game->avatar->fhTo(true);
warpToSceneNode("FOREST03", "WARPKEY");
}
}
void Game::warpKey4()
{
if (core->getCtrlState())
{
dsq->game->avatar->heal(1000);
dsq->game->avatar->fhTo(true);
warpToSceneNode("ABYSS01", "WARPKEY");
}
}
int game_collideParticle(Vector pos)
{
bool aboveWaterLine = (pos.y <= dsq->game->waterLevel.x+20);
@ -6039,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++)
@ -6197,7 +5958,6 @@ void Game::action(int id, int state)
if (foodSlots[i]->isCursorIn() && foodSlots[i]->getIngredient())
{
foodSlots[i]->moveRight();
adjustFoodSlotCursor();
break;
}
}
@ -6234,7 +5994,6 @@ void Game::action(int id, int state)
if (ingrIndex >= 0)
{
foodSlots[ingrIndex]->discard();
adjustFoodSlotCursor();
}
}
}
@ -6377,7 +6136,8 @@ void Game::applyState()
core->afterEffectManager->clear();
//core->afterEffectManager->addEffect(new RippleEffect());
}
Shot::shots.clear();
Shot::shots.clear(); // the shots were deleted elsewhere, drop any remaining pointers
Shot::deleteShots.clear();
backdropQuad = 0;
clearObsRows();
inGameMenu = false;
@ -6884,9 +6644,6 @@ void Game::applyState()
toNode = "";
spawnSporeChildren();
createInGameMenu();
hideInGameMenu(false);
@ -6914,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
/*
@ -7058,24 +6823,11 @@ void Game::bindInput()
#ifdef AQUARIA_BUILD_SCENEEDITOR
if (dsq->canOpenEditor())
{
//addAction(MakeFunctionEvent(Game, toggleSceneEditor), KEY_TAB, 0);
addAction(ACTION_TOGGLESCENEEDITOR, KEY_TAB);
}
#endif
/*
if (dsq->user.demo.warpKeys)
{
addAction(MakeFunctionEvent(Game, warpKey1), KEY_1, 1);
addAction(MakeFunctionEvent(Game, warpKey2), KEY_2, 1);
addAction(MakeFunctionEvent(Game, warpKey3), KEY_3, 1);
addAction(MakeFunctionEvent(Game, warpKey4), KEY_4, 1);
}
*/
dsq->user.control.actionSet.importAction(this, "PrimaryAction", ACTION_PRIMARY);
dsq->user.control.actionSet.importAction(this, "Escape", ACTION_ESC);
@ -7128,6 +6880,20 @@ void Game::bindInput()
addAction(ACTION_MENUUP, JOY1_STICK_UP);
addAction(ACTION_MENUDOWN, JOY1_STICK_DOWN);
// To capture quick song keys via script
dsq->user.control.actionSet.importAction(this, "SongSlot1", ACTION_SONGSLOT1);
dsq->user.control.actionSet.importAction(this, "SongSlot2", ACTION_SONGSLOT2);
dsq->user.control.actionSet.importAction(this, "SongSlot3", ACTION_SONGSLOT3);
dsq->user.control.actionSet.importAction(this, "SongSlot4", ACTION_SONGSLOT4);
dsq->user.control.actionSet.importAction(this, "SongSlot5", ACTION_SONGSLOT5);
dsq->user.control.actionSet.importAction(this, "SongSlot6", ACTION_SONGSLOT6);
dsq->user.control.actionSet.importAction(this, "SongSlot7", ACTION_SONGSLOT7);
dsq->user.control.actionSet.importAction(this, "SongSlot8", ACTION_SONGSLOT8);
dsq->user.control.actionSet.importAction(this, "SongSlot9", ACTION_SONGSLOT9);
dsq->user.control.actionSet.importAction(this, "SongSlot10", ACTION_SONGSLOT10);
dsq->user.control.actionSet.importAction(this, "Revert", ACTION_REVERT);
if (avatar)
avatar->bindInput();
@ -7277,10 +7043,18 @@ void Game::onUseTreasure()
if (selectedTreasureFlag != -1)
{
dsq->runScriptNum("scripts/global/menu-treasures.lua", "useTreasure", selectedTreasureFlag);
onUseTreasure(selectedTreasureFlag);
}
}
void Game::onUseTreasure(int flag)
{
if(dsq->mod.isActive())
dsq->runScriptNum(dsq->mod.getPath() + "scripts/menu-treasures.lua", "useTreasure", flag);
else
dsq->runScriptNum("scripts/global/menu-treasures.lua", "useTreasure", flag);
}
Recipe *Game::findRecipe(const std::vector<IngredientData*> &list)
{
if (list.size() < 2) return 0;
@ -7440,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");
@ -7620,6 +7409,8 @@ void Game::onCook()
}
refreshFoodSlots(true);
endcook:
AquariaGuiElement::canDirMoveGlobal = true;
isCooking = false;
@ -8346,26 +8137,25 @@ bool Game::collideCircleVsCircle(Entity *a, Entity *b)
return (a->position - b->position).isLength2DIn(a->collideRadius + b->collideRadius);
}
bool Game::collideHairVsCircle(Entity *a, int num, const Vector &pos2, int radius, float perc)
bool Game::collideHairVsCircle(Entity *a, int num, const Vector &pos2, int radius, float perc, int *colSegment)
{
if (perc == 0)
perc = 1;
bool c = false;
if (a->hair)
if (a && a->hair)
{
if (a)
if (num == 0)
num = a->hair->hairNodes.size();
// HACK: minus 2
for (int i = 0; i < num; i++)
{
if (num == 0)
num = a->hair->hairNodes.size();
// HACK: minus 2
for (int i = 0; i < num; i++)
// + a->hair->position
c = ((a->hair->hairNodes[i].position) - pos2).isLength2DIn(a->hair->hairWidth*perc + radius);
if (c)
{
// + a->hair->position
c = ((a->hair->hairNodes[i].position) - pos2).isLength2DIn(a->hair->hairWidth*perc + radius);
if (c)
{
return true;
}
if (colSegment)
*colSegment = i;
return true;
}
}
}
@ -8525,8 +8315,6 @@ void Game::preLocalWarp(LocalWarpType localWarpType)
{
dsq->game->avatar->warpInLocal = Vector(0,0,0);
}
dsq->game->avatar->warpIn = !dsq->game->avatar->warpIn;
dsq->screenTransition->capture();
core->resetTimer();
@ -8557,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;
}
@ -8568,24 +8356,17 @@ bool Game::isEntityCollideWithShot(Entity *e, Shot *shot)
}
if (e->getEntityType() == ET_ENEMY)
{
if (shot->firer != e)
if (shot->getDamageType() == DT_AVATAR_BITE)
{
if (shot->getDamageType() == DT_AVATAR_BITE)
Avatar::BittenEntities::iterator i;
for (i = avatar->bittenEntities.begin(); i != avatar->bittenEntities.end(); i++)
{
Avatar::BittenEntities::iterator i;
for (i = avatar->bittenEntities.begin(); i != avatar->bittenEntities.end(); i++)
if (e == (*i))
{
if (e == (*i))
{
return false;
}
return false;
}
return true;
}
}
else
{
return false;
return true;
}
}
else if (e->getEntityType() == ET_AVATAR)
@ -8608,10 +8389,10 @@ void Game::handleShotCollisions(Entity *e, bool hasShield)
{
BBGE_PROF(Game_handleShotCollisions);
bool isRegValid=true;
for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); i++)
for (size_t i = 0; i < Shot::shots.size(); ++i)
{
Shot *shot = *i;
if (isEntityCollideWithShot(e, shot) && (!hasShield || (!shot->shotData || !shot->shotData->ignoreShield)))
Shot *shot = Shot::shots[i];
if (shot->isActive() && isEntityCollideWithShot(e, shot) && (!hasShield || (!shot->shotData || !shot->shotData->ignoreShield)))
{
Vector collidePoint = e->position+e->offset;
if (e->getNumTargetPoints()>0)
@ -8640,10 +8421,10 @@ bool Game::isDamageTypeEnemy(DamageType dt)
void Game::handleShotCollisionsSkeletal(Entity *e)
{
BBGE_PROF(Game_HSSKELETAL);
for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); i++)
for (size_t i = 0; i < Shot::shots.size(); ++i)
{
Shot *shot = *i;
if (isEntityCollideWithShot(e, shot))
Shot *shot = Shot::shots[i];
if (shot->isActive() && isEntityCollideWithShot(e, shot))
{
Bone *b = collideSkeletalVsCircle(e, shot->position, shot->collideRadius);
if (b)
@ -8657,10 +8438,10 @@ void Game::handleShotCollisionsSkeletal(Entity *e)
void Game::handleShotCollisionsHair(Entity *e, int num)
{
for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); i++)
for (size_t i = 0; i < Shot::shots.size(); ++i)
{
Shot *shot = *i;
if (isEntityCollideWithShot(e, shot))
Shot *shot = Shot::shots[i];
if (shot->isActive() && isEntityCollideWithShot(e, shot))
{
bool b = collideHairVsCircle(e, num, shot->position, 8);
if (b)
@ -8946,7 +8727,6 @@ void Game::refreshFoodSlots(bool effects)
{
foodSlots[i]->refresh(effects);
}
adjustFoodSlotCursor();
}
void Game::refreshTreasureSlots()
@ -10178,7 +9958,7 @@ void Game::update(float dt)
if (avatar)
{
tintColor.update(dt);
/*tintColor.update(dt);
if (core->afterEffectManager)
{
if (tintColor.isInterpolating())
@ -10187,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));
@ -10925,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);
@ -11006,6 +10781,7 @@ void Game::removeState()
debugLog("killAllShots");
Shot::killAllShots();
Shot::clearShotGarbage(); // make sure there are no pointers left (would lead to a crash on shutdown otherwise)
debugLog("killAllBeams");
Beam::killAllBeams();
debugLog("killAllWebs");

View file

@ -125,7 +125,6 @@ typedef std::vector<EntityGroup> EntityGroups;
enum EditTypes
{
ET_NONE =-1,
ET_ELEMENTS =0,
ET_ENTITIES =1,
ET_PATHS =2,
@ -418,7 +417,6 @@ public:
void closeMainMenu();
void setBackgroundGradient();
void addSpringPlant();
bool isOn();
@ -472,12 +470,10 @@ public:
void moveLayer();
void moveElementToLayer(Element *e, int bgLayer);
void toggleElementRepeat();
void setGroup();
bool multiSelecting;
Vector multiSelectPoint;
std::vector <Element*> selectedElements;
void fixEntityIDs();
void bindNodeToEntity();
Vector groupCenter;
Vector getSelectedElementsCenter();
@ -610,9 +606,9 @@ enum ObsType
struct EntitySaveData
{
public:
EntitySaveData(Entity *e, int idx, int x, int y, int rot, int group, int id, const std::string &name) : e(e), idx(idx), x(x), y(y), rot(rot), group(group), id(id), name(name) {}
EntitySaveData(Entity *e, int idx, int x, int y, int rot, int id, const std::string &name) : e(e), idx(idx), x(x), y(y), rot(rot), id(id), name(name) {}
Entity *e;
int idx, x, y, rot, group, id;
int idx, x, y, rot, id;
std::string name;
};
@ -651,7 +647,6 @@ public:
void updatePreviewRecipe();
void transitionToScene(std::string scene);
void transitionToSceneUnder(std::string scene);
bool loadScene(std::string scene);
void clearGrid(int v = 0);
@ -677,7 +672,7 @@ public:
bool collideBoxWithGrid(const Vector& position, int w, int h);
bool collideCircleWithGrid(const Vector& position, int r);
bool collideHairVsCircle(Entity *a, int num, const Vector &pos2, int radius, float perc=0);
bool collideHairVsCircle(Entity *a, int num, const Vector &pos2, int radius, float perc=0, int *colSegment=0);
bool collideCircleVsCircle(Entity *a, Entity *b);
Bone *collideSkeletalVsCircle(Entity *skeletal, Entity *circle);
@ -699,7 +694,6 @@ public:
WarpAreas warpAreas;
void postInitEntities();
Entity *getEntityInGroup(int gid, int iter);
EntityClass *getEntityClassForEntityType(const std::string &type);
void warpToArea(WarpArea *area);
@ -720,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;
@ -744,9 +740,9 @@ public:
MiniMapHint miniMapHint;
void updateMiniMapHintPosition();
EntitySaveData *getEntitySaveDataForEntity(Entity *e, Vector pos);
Entity *createEntity(int idx, int id, Vector position, int rot, bool createSaveData, std::string name, EntityType = ET_ENEMY, Entity::NodeGroups *nodeGroups=0, int groupID=0, bool doPostInit=false);
Entity *createEntity(const std::string &type, int id, Vector position, int rot, bool createSaveData, std::string name, EntityType = ET_ENEMY, Entity::NodeGroups *nodeGroups=0, int groupID=0, bool doPostInit=false);
Entity *establishEntity(Entity *e, int id=0, Vector position=Vector(0,0), int rot=0, bool createSaveData=false, std::string name="", EntityType = ET_ENEMY, Entity::NodeGroups *nodeGroups=0, int groupID=0, bool doPostInit=false);
Entity *createEntity(int idx, int id, Vector position, int rot, bool createSaveData, std::string name, EntityType = ET_ENEMY, bool doPostInit=false);
Entity *createEntity(const std::string &type, int id, Vector position, int rot, bool createSaveData, std::string name, EntityType = ET_ENEMY, bool doPostInit=false);
Entity *establishEntity(Entity *e, int id=0, Vector position=Vector(0,0), int rot=0, bool createSaveData=false, std::string name="", EntityType = ET_ENEMY,bool doPostInit=false);
void setCameraFollow(RenderObject *r);
void setCameraFollowEntity(Entity *e);
void setMenuDescriptionText(const std::string &text);
@ -886,9 +882,6 @@ public:
int worldMapIndex;
void spawnSporeChildren();
bool creatingSporeChildren;
bool loadingScene;
WaterSurfaceRender *waterSurfaceRender;
@ -901,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;
@ -943,6 +937,7 @@ public:
void onRecipes();
void updateCookList();
void onUseTreasure();
void onUseTreasure(int flag);
void onPrevFoodPage();
void onNextFoodPage();
@ -1009,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();
@ -1051,10 +1049,6 @@ protected:
void warpPrep();
void warpKey1();
void warpKey2();
void warpKey3();
void warpKey4();
bool shuttingDownGameState;
void onOptionsMenu();
bool optionsMenu, foodMenu, petMenu, treasureMenu, keyConfigMenu;
@ -1170,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

@ -83,18 +83,31 @@ static void CheckConfig(void)
extern "C" int main(int argc,char *argv[])
{
std::string dsqParam = ""; // fileSystem
std::string extraDataDir = "";
const char *envPath = 0;
#ifdef BBGE_BUILD_UNIX
const char *envPath = getenv("AQUARIA_DATA_PATH");
if (envPath != NULL)
envPath = getenv("AQUARIA_DATA_PATH");
if (envPath)
{
dsqParam = envPath;
}
#endif
#ifdef AQUARIA_DEFAULT_DATA_DIR
if(!envPath)
dsqParam = AQUARIA_DEFAULT_DATA_DIR;
#endif
#ifdef AQUARIA_EXTRA_DATA_DIR
if(!envPath)
extraDataDir = AQUARIA_EXTRA_DATA_DIR;
#endif
#endif
CheckConfig();
{
DSQ dsql(dsqParam);
DSQ dsql(dsqParam, extraDataDir);
dsql.init();
dsql.main();
dsql.shutdown();

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

@ -146,6 +146,9 @@ static void init()
#ifdef AQUARIA_CUSTOM_BUILD_ID
os << AQUARIA_CUSTOM_BUILD_ID;
#endif
#ifdef AQUARIA_OVERRIDE_VERSION_STRING
os << "|" << AQUARIA_OVERRIDE_VERSION_STRING;
#endif
const char *loc = getUsedLocale();
if(*loc)
@ -241,6 +244,9 @@ void download(RequestData *rq)
void update()
{
if(!netUp)
return;
RequestDataHolder h;
while(notifyRequests.pop(h))
h.rq->notify(h.ev, h.recvd, h.total);

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

@ -643,9 +643,6 @@ void SceneEditor::init()
addAction(MakeFunctionEvent(SceneEditor, mouseButtonLeftUp), MOUSE_BUTTON_LEFT, 0);
addAction(MakeFunctionEvent(SceneEditor, mouseButtonRightUp), MOUSE_BUTTON_RIGHT, 0);
// removed in fc3
//addAction(MakeFunctionEvent(SceneEditor, bindNodeToEntity), KEY_B, 0);
addAction(MakeFunctionEvent(SceneEditor, alignHorz), KEY_C, 1);
addAction(MakeFunctionEvent(SceneEditor, alignVert), KEY_V, 1);
@ -879,38 +876,6 @@ void SceneEditor::createAquarian()
inCreateAqurian = false;
}
void SceneEditor::bindNodeToEntity()
{
if (editType == ET_PATHS)
{
Path *p = getSelectedPath();
if (p)
{
std::istringstream is(dsq->getUserInputString("Enter group number"));
int group = 0;
is >> group;
Entity *e = getEntityAtCursor();
if (e)
{
e->removeNodeFromAllNodeGroups(p);
e->addNodeToNodeGroup(group, p);
}
else
{
debugLog("no entity at cursor");
}
}
}
}
void SceneEditor::addSpringPlant()
{
/*
SpringPlant *s = new SpringPlant(dsq->getGameCursorPosition());
dsq->game->addRenderObject(s, LR_ENTITIES);
*/
}
Path *SceneEditor::getSelectedPath()
{
if (selectedIdx >= 0 && selectedIdx < dsq->game->getNumPaths())
@ -1472,7 +1437,6 @@ void SceneEditor::updateEntitySaveData(Entity *editingEntity)
os << "idx2: " << editingEntity->entityTypeIdx << " ";
os << "name: " << editingEntity->name;
//os << "state: " << editingEntity->getState();
os << "groupID: " << editingEntity->getGroupID();
debugLog(os.str());
//debugLog("changing entity save data");
d->x = editingEntity->position.x;
@ -1484,7 +1448,6 @@ void SceneEditor::updateEntitySaveData(Entity *editingEntity)
debugLog(os2.str());
*/
d->rot = editingEntity->rotation.z;
d->group = editingEntity->getGroupID();
}
else
{
@ -1636,25 +1599,6 @@ void SceneEditor::toggleElementHurt()
}
}
void SceneEditor::setGroup()
{
if (editingEntity)
{
std::ostringstream os;
os << editingEntity->getGroupID();
Entity *backup = editingEntity;
std::string value = dsq->getUserInputString("Enter Group", os.str());
int group = 0;
if (!value.empty())
{
std::istringstream is(value);
is >> group;
}
backup->setGroupID(group);
updateEntitySaveData(backup);
}
}
void SceneEditor::toggleElementRepeat()
{
if (editingElement)
@ -2594,6 +2538,7 @@ void SceneEditor::loadScene()
Shot::loadShotBank(dsq->shotBank1, dsq->shotBank2);
dsq->game->loadEntityTypeList();
dsq->loadElementEffects();
dsq->continuity.loadSongBank();
}
void SceneEditor::saveScene()
@ -3134,9 +3079,9 @@ void SceneEditor::placeElement()
else if (editType == ET_ENTITIES)
{
if (!selectedEntity.nameBased)
dsq->game->createEntity(selectedEntity.index, 0, dsq->getGameCursorPosition(), 0, true, "", ET_ENEMY, 0, 0, true);
dsq->game->createEntity(selectedEntity.index, 0, dsq->getGameCursorPosition(), 0, true, "", ET_ENEMY, true);
else
dsq->game->createEntity(selectedEntity.name, 0, dsq->getGameCursorPosition(), 0, true, "", ET_ENEMY, 0, 0, true);
dsq->game->createEntity(selectedEntity.name, 0, dsq->getGameCursorPosition(), 0, true, "", ET_ENEMY, true);
}
else if (editType == ET_PATHS)
{
@ -3373,12 +3318,16 @@ void SceneEditor::updateText()
os << "entities (" << dsq->entities.size() << ")";
if (editingEntity)
{
os.precision(1);
os << std::fixed;
os << " id: " << editingEntity->getID()
<< " name: " << editingEntity->name
<< " flag:" << dsq->continuity.getEntityFlag(dsq->game->sceneName, editingEntity->getID())
<< " fh:" << editingEntity->isfh()
<< " fv:" << editingEntity->isfv()
<< " state:" << editingEntity->getState();
<< " state:" << editingEntity->getState()
<< " et:" << editingEntity->getEntityType()
<< " hp:" << editingEntity->health << "/" << editingEntity->maxHealth;
}
break;
case ET_PATHS:
@ -3563,14 +3512,14 @@ void SceneEditor::update(float dt)
if (core->getShiftState() && !core->getCtrlState()) // hackish: to prevent accidental recache()
nextElement();
else
zoom /= 1.05f;
zoom /= 1.12f;
}
else if (core->mouse.scrollWheelChange > 0)
{
if (core->getShiftState() && !core->getCtrlState()) // hackish: to prevent accidental entity selection
prevElement();
else
zoom *= 1.05f;
zoom *= 1.12f;
}
if (zoom.x < 0.04f)
zoom.x = zoom.y = 0.04f;
@ -3629,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;

File diff suppressed because it is too large Load diff

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

@ -30,7 +30,6 @@ ScriptedEntity::ScriptedEntity(const std::string &scriptName, Vector position, E
{
addType(SCO_SCRIPTED_ENTITY);
crushDelay = 0;
autoSkeletalSpriteUpdate = true;
script = 0;
songNoteFunction = songNoteDoneFunction = true;
addChild(&pullEmitter, PM_STATIC);
@ -83,7 +82,7 @@ ScriptedEntity::ScriptedEntity(const std::string &scriptName, Vector position, E
void ScriptedEntity::setAutoSkeletalUpdate(bool v)
{
autoSkeletalSpriteUpdate = v;
skeletalSprite.ignoreUpdate = !v;
}
void ScriptedEntity::message(const std::string &msg, int v)
@ -181,41 +180,6 @@ void ScriptedEntity::registerNewPart(RenderObject *r, const std::string &name)
partMap[name] = r;
}
void ScriptedEntity::initHair(int numSegments, int segmentLength, int width, const std::string &tex)
{
if (hair)
{
errorLog("Trying to init hair when hair is already present");
}
hair = new Hair(numSegments, segmentLength, width);
hair->setTexture(tex);
dsq->game->addRenderObject(hair, layer);
}
void ScriptedEntity::setHairHeadPosition(const Vector &pos)
{
if (hair)
{
hair->setHeadPosition(pos);
}
}
void ScriptedEntity::updateHair(float dt)
{
if (hair)
{
hair->updatePositions();
}
}
void ScriptedEntity::exertHairForce(const Vector &force, float dt)
{
if (hair)
{
hair->exertForce(force, dt);
}
}
void ScriptedEntity::initSegments(int numSegments, int minDist, int maxDist, std::string bodyTex, std::string tailTex, int w, int h, float taper, bool reverseSegments)
{
this->reverseSegments = reverseSegments;
@ -640,13 +604,8 @@ void ScriptedEntity::onUpdate(float dt)
}
*/
if (!autoSkeletalSpriteUpdate)
skeletalSprite.ignoreUpdate = true;
CollideEntity::onUpdate(dt);
if (!autoSkeletalSpriteUpdate)
skeletalSprite.ignoreUpdate = false;
//updateStrands(dt);
if (becomeSolidDelay)
@ -800,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

@ -38,7 +38,6 @@ public:
void setEntityLayer(int layer);
void setupEntity(const std::string &tex, int layer=0);
void setupBasicEntity(const std::string& texture, int health, int manaBall, int exp, int money, int collideRadius, int state, int w, int h, int expType, bool hitEntity, int updateCull, int layer);
void initHair(int numSegments, int segmentLength, int width, const std::string &tex);
void initSegments(int numSegments, int minDist, int maxDist, std::string bodyTex, std::string tailTex, int w, int h, float taper, bool reverseSegments);
void registerNewPart(RenderObject *r, const std::string &name);
typedef std::map<std::string, RenderObject*> PartMap;
@ -69,12 +68,8 @@ public:
typedef std::vector<Strand*> Strands;
Strands strands;
int strandSpacing;
bool isEntityInside();
void becomeSolid();
void updateHair(float dt);
void setHairHeadPosition(const Vector &pos);
void exertHairForce(const Vector &force, float dt);
std::string deathParticleEffect;
ParticleEffect pullEmitter;
@ -93,7 +88,6 @@ protected:
void onDieEaten();
void luaDebugMsg(const std::string &func, const std::string &msg);
float crushDelay;
bool autoSkeletalSpriteUpdate;
int beforePullMaxSpeed;
bool songNoteFunction, preUpdateFunc;
bool songNoteDoneFunction;

View file

@ -26,7 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../BBGE/MathFunctions.h"
Shot::Shots Shot::shots;
Shot::Shots Shot::deleteShots;
Shot::ShotBank Shot::shotBank;
unsigned int Shot::shotsIter = 0;
std::string Shot::shotBankPath = "";
@ -92,6 +94,9 @@ void ShotData::bankLoad(const std::string &file, const std::string &path)
checkDamageTarget = true;
}
this->name = file;
stringToLower(this->name);
debugLog(usef);
char *data = readFile(core->adjustFilenameCase(usef).c_str());
if (!data)
@ -225,6 +230,8 @@ void ShotData::bankLoad(const std::string &file, const std::string &path)
damageType = DT_ENEMY_CREATOR;
else if (bt == "DT_ENEMY_MANTISBOMB")
damageType = DT_ENEMY_MANTISBOMB;
else
damageType = (DamageType)atoi(bt.c_str());
}
else if (token == "Invisible")
inf >> invisible;
@ -335,6 +342,8 @@ Shot::Shot() : Quad(), Segmented(0,0)
fired = false;
target = 0;
dead = false;
enqueuedForDelete = false;
shotIdx = shots.size();
shots.push_back(this);
}
@ -479,12 +488,19 @@ void Shot::setLifeTime(float l)
void Shot::onEndOfLife()
{
destroySegments(0.2);
shots.remove(this);
dead = true;
if (emitter)
{
emitter->killParticleEffect();
emitter = 0;
}
if (!enqueuedForDelete)
{
enqueuedForDelete = true;
deleteShots.push_back(this);
}
}
void Shot::doHitEffects()
@ -515,7 +531,7 @@ void Shot::onHitWall()
{
if (!shotData->spawnEntity.empty())
{
dsq->game->createEntity(shotData->spawnEntity, 0, position, 0, false, "", ET_ENEMY, 0, 0, true);
dsq->game->createEntity(shotData->spawnEntity, 0, position, 0, false, "", ET_ENEMY, true);
//(shotData->spawnEntity, 0, position, 0, false, "");
if (shotData->spawnEntity == "NatureFormFlowers")
{
@ -531,24 +547,31 @@ void Shot::onHitWall()
void Shot::killAllShots()
{
std::queue<Shot*>shotDeleteQueue;
for (Shots::iterator i = shots.begin(); i != shots.end(); i++)
{
shotDeleteQueue.push(*i);
}
Shot *s = 0;
while (!shotDeleteQueue.empty())
{
s = shotDeleteQueue.front();
if (s)
{
s->safeKill();
}
shotDeleteQueue.pop();
}
shots.clear();
for (Shots::iterator i = shots.begin(); i != shots.end(); ++i)
(*i)->safeKill();
}
void Shot::clearShotGarbage()
{
for(size_t i = 0; i < deleteShots.size(); ++i)
{
Shot *s = deleteShots[i];
const unsigned int idx = s->shotIdx;
// move last shot to deleted one and shorten vector
if(idx < shots.size() && shots[idx] == s)
{
Shot *lastshot = shots.back();
shots[idx] = lastshot;
lastshot->shotIdx = idx;
shots.pop_back();
}
else
errorLog("Shot::clearShotGarbage(): wrong index in shot vector");
}
deleteShots.clear();
}
void Shot::reflectFromEntity(Entity *e)
{
Entity *oldFirer = firer;
@ -761,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

@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
struct ShotData
{
ShotData();
std::string texture;
std::string texture, name;
std::string hitSfx, bounceSfx, fireSfx;
std::string hitPrt, trailPrt, firePrt, bouncePrt;
std::string spawnEntity;
@ -79,11 +79,15 @@ public:
//void destroy();
void reflectFromEntity(Entity *e);
void setParticleEffect(const std::string &particleEffect);
typedef std::list<Shot*> Shots;
static Shots shots;
typedef std::vector<Shot*> Shots;
static Shots shots, deleteShots;
static unsigned int shotsIter; // for script
static Shot *getFirstShot() { shotsIter = 0; return getNextShot(); }
static Shot *getNextShot() { return shotsIter < shots.size() ? shots[shotsIter++] : NULL; }
static std::string shotBankPath;
static void targetDied(Entity *t);
static void killAllShots();
static void clearShotGarbage();
Entity *target, *firer;
int maxSpeed, targetPt;
@ -117,12 +121,13 @@ public:
void updatePosition();
bool isHitEnts() const;
bool isObstructed(float dt) const;
inline bool isActive() const { return !dead; }
inline const char *getName() const { return shotData ? shotData->name.c_str() : ""; }
float extraDamage;
protected:
float waveTimer;
bool fired;
void suicide();
@ -135,7 +140,12 @@ protected:
void onEndOfLife();
bool dead;
bool fired;
bool enqueuedForDelete;
void onUpdate(float dt);
private:
unsigned int shotIdx;
};
class Beam : public Quad

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();
@ -43,46 +43,11 @@ AfterEffectManager::AfterEffectManager(int xDivs, int yDivs)
this->yDivs = 0;
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();
Shader *activeShader=0;
if (core->frameBuffer.isInited())
int firstShader = -1;
int lastShader = -1;
Shader *activeShader = 0;
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);
@ -382,9 +342,6 @@ void AfterEffectManager::renderGrid()
//glDisable(GL_TEXTURE_2D);
RenderObject::lastTextureApplied = 0;
glBindTexture(GL_TEXTURE_2D, 0);
if (activeShader)
activeShader->unbind();
//bwShader.unbind();
//glActiveTextureARB(GL_TEXTURE0_ARB);
@ -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;
Vector ** drawGrid;
// 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;
ActiveShader activeShader;
};

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

@ -41,6 +41,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#if BBGE_BUILD_WINDOWS
#include <shlobj.h>
#include <direct.h>
#endif
#ifdef BBGE_BUILD_SDL
@ -817,7 +818,7 @@ bool Core::getMetaState()
void Core::errorLog(const std::string &s)
{
messageBox("Message", s);
messageBox("Error!", s);
debugLog(s);
}
@ -827,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)
@ -884,12 +876,13 @@ static bool checkWritable(const std::string& path, bool warn, bool critical)
const float SORT_DELAY = 10;
Core::Core(const std::string &filesystem, int numRenderLayers, const std::string &appName, int particleSize, std::string userDataSubFolder)
Core::Core(const std::string &filesystem, const std::string& extraDataDir, int numRenderLayers, const std::string &appName, int particleSize, std::string userDataSubFolder)
: ActionMapper(), StateManager(), appName(appName)
{
sound = NULL;
screenCapScale = Vector(1,1,1);
timeUpdateType = TIMEUPDATE_DYNAMIC;
_extraDataDir = extraDataDir;
fixedFPS = 60;
@ -1093,6 +1086,13 @@ void Core::initPlatform(const std::string &filesystem)
}
#endif
#ifdef BBGE_BUILD_WINDOWS
if(filesystem.length())
{
if(_chdir(filesystem.c_str()) != 0)
{
debugLog("chdir failed: " + filesystem);
}
}
// FIXME: filesystem not handled
#endif
}
@ -1267,7 +1267,7 @@ void Core::init()
if((SDL_Init(0))==-1)
{
exit(0);
exit_error("Failed to init SDL");
}
#endif
@ -1778,7 +1778,6 @@ void Core::onUpdate(float dt)
//script.update(dt);
cameraPos.update(dt);
cameraRot.update(dt);
globalScale.update(dt);
if (afterEffectManager)
@ -1841,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
@ -1909,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
}
@ -1942,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
@ -1952,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
}
@ -2624,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;
@ -2736,6 +2727,13 @@ bool Core::isWindowFocus()
return true;
}
void Core::onBackgroundUpdate()
{
#if BBGE_BUILD_SDL
SDL_Delay(200);
#endif
}
void Core::main(float runTime)
{
bool verbose = coreVerboseDebug;
@ -2920,7 +2918,7 @@ void Core::main(float runTime)
{
pollEvents();
//debugLog("app not in input focus");
SDL_Delay(200);
onBackgroundUpdate();
resetTimer();
}
@ -3007,6 +3005,8 @@ void Core::main(float runTime)
updateCullData();
dbg_numRenderCalls = 0;
if (settings.renderOn)
{
if (verbose) debugLog("dark layer prerender");
@ -3162,10 +3162,8 @@ void Core::clearBuffers()
void Core::setupRenderPositionAndScale()
{
#ifdef BBGE_BUILD_OPENGL
//glRotatef(cameraRot.z, 0, 0, 1);
glScalef(globalScale.x*globalResolutionScale.x*screenCapScale.x, globalScale.y*globalResolutionScale.y*screenCapScale.y, globalScale.z*globalResolutionScale.z);
glTranslatef(-(cameraPos.x+cameraOffset.x), -(cameraPos.y+cameraOffset.y), -(cameraPos.z+cameraOffset.z));
//glRotatef(180, 0, 1, 0);
#endif
}
@ -3851,10 +3849,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)
{
@ -3884,6 +3878,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)
@ -3950,15 +3949,8 @@ void Core::clearResources()
{
deletedResources.push_back (resources[i]);
Resource *r = resources[i];
try
{
r->destroy();
delete r;
}
catch(...)
{
errorLog("Resource could not be deleted " + resourceNames[i]);
}
r->destroy();
delete r;
}
}
resourceNames.clear();
@ -4845,22 +4837,35 @@ 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();
// TODO: mount and other stuff
ttvfs::VFSDir *override = vfs.GetDir("override");
if(override)
{
debugLog("Mounting override dir...");
override->load(true);
vfs.Mount("override", "", true);
}
// If we ever want to read from a container...
//vfs.AddArchive("aqfiles.zip", false, "");
if(_extraDataDir.length())
{
debugLog("Mounting extra data dir: " + _extraDataDir);
vfs.MountExternalPath(_extraDataDir.c_str(), "", true, true);
}
debugLog("Done");
#endif

View file

@ -973,7 +973,7 @@ public:
NO_DESTROY
};
// init
Core(const std::string &filesystem, int numRenderLayers, const std::string &appName="BBGE", int particleSize=1024, std::string userDataSubFolder="");
Core(const std::string &filesystem, const std::string& extraDataDir, int numRenderLayers, const std::string &appName="BBGE", int particleSize=1024, std::string userDataSubFolder="");
void initPlatform(const std::string &filesystem);
~Core();
@ -1133,7 +1133,7 @@ public:
virtual void onPlayedVoice(const std::string &name){}
InterpolatedVector cameraPos, cameraRot;
InterpolatedVector cameraPos;
int fps;
bool loopDone;
@ -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,9 @@ 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;
virtual void onBackgroundUpdate();
protected:
@ -1402,6 +1403,7 @@ protected:
virtual void onRender(){}
void setupFileAccess();
std::string _extraDataDir;
};
extern Core *core;

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

@ -155,6 +155,9 @@ void ParticleManager::updateParticle(Particle *p, float dt)
if (suckPos)
{
Vector dir = (*suckPos) - p->emitter->getWorldCollidePosition(p->pos);
//HACK: what? ->
if (!p->emitter->data.spawnLocal && p->emitter->getParent())
dir += p->emitter->getParent()->position;
dir.setLength2D(p->emitter->data.suckStr);
p->vel += dir * dt;
}

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

@ -45,10 +45,6 @@ public:
ref--;
if (ref == 0)
destroy();
/*
else if (ref < 0)
throw std::exception("ref count out of bounds < 0");
*/
}
int getRef() { return ref; }
std::string name;

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()
@ -226,13 +172,8 @@ void Shader::bind()
#ifdef BBGE_BUILD_SHADERS
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);
glUseProgramObjectARB(g_programObj);
_flushUniforms();
#endif
}
@ -241,150 +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;
this->vertFile = file;
this->fragFile = fragFile;
try
{
char *vertCode = file.length() ? readFile(file) : NULL;
char *fragCode = fragFile.length() ? readFile(fragFile) : NULL;
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...
//
loadSrc(vertCode, fragCode);
const char *vertexShaderStrings[1];
const char *fragmentShaderStrings[1];
GLint bVertCompiled;
GLint bFragCompiled;
GLint bLinked;
char str[4096];
//
// 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)
{
glGetInfoLogARB(g_vertexShader, sizeof(str), NULL, str);
std::ostringstream os;
os << "Vertex Shader Compile Error: " << str;
debugLog(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 )
{
glGetInfoLogARB( g_fragmentShader, sizeof(str), NULL, str );
std::ostringstream os;
os << "Fragment Shader Compile Error: " << str;
debugLog(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)
{
debugLog("programObj / vertexShader / fragmentShader problem");
return;
}
glAttachObjectARB( g_programObj, g_vertexShader );
glAttachObjectARB( g_programObj, g_fragmentShader );
//
// Link the program object and print out the info log...
//
glLinkProgramARB( g_programObj );
glGetObjectParameterivARB( g_programObj, GL_OBJECT_LINK_STATUS_ARB, &bLinked );
debugLog("Shader::load 5");
if( bLinked == false )
{
glGetInfoLogARB( g_programObj, sizeof(str), NULL, str );
std::ostringstream os;
os << "Shader Linking Error: " << str;
debugLog(os.str());
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;
}
catch(...)
{
debugLog("caught exception in shader::load");
loaded = false;
}
#endif
debugLog("End Shader::load()");
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...
//
if(vertCode && *vertCode && !(vertexShader = _compileShader(GL_VERTEX_SHADER_ARB, vertCode, str, sizeof(str))))
{
std::ostringstream os;
os << "Vertex Shader Compile Error [" << vertFile << "]:\n" << str;
errorLog(os.str());
return;
}
//
// Create the fragment shader...
//
if(fragCode && *fragCode && !(fragmentShader = _compileShader(GL_FRAGMENT_SHADER_ARB, fragCode, str, sizeof(str))))
{
std::ostringstream os;
os << "Fragment Shader Compile Error [" << fragFile << "]:\n" << str;
errorLog(os.str());
return;
}
//
// Create a program object and attach the two compiled shaders...
//
g_programObj = glCreateProgramObjectARB();
if (!(g_programObj && (vertexShader || fragmentShader)))
{
errorLog("programObj / vertexShader / fragmentShader problem");
unload();
return;
}
//
// 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 );
if(!bLinked)
{
glGetInfoLogARB( g_programObj, sizeof(str), NULL, str );
std::ostringstream os;
os << "Shader Linking Error: " << str;
errorLog(os.str());
unload();
return;
}
_queryUniforms();
#endif
}
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

@ -461,7 +461,7 @@ void AnimationLayer::playAnimation(int idx, int loop)
//doNextKeyframe();
}
void AnimationLayer::enqueueAnimation(std::string anim, int loop)
void AnimationLayer::enqueueAnimation(const std::string& anim, int loop)
{
enqueuedAnimation = anim;
enqueuedAnimationLoop = loop;
@ -507,14 +507,13 @@ 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];
}
bool AnimationLayer::createTransitionAnimation(std::string anim, float time)
bool AnimationLayer::createTransitionAnimation(const std::string& anim, float time)
{
//Animation *a = getCurrentAnimation();
Animation *to = s->getAnimation(anim);
@ -555,6 +554,7 @@ void AnimationLayer::stopAnimation()
{
animate(enqueuedAnimation, enqueuedAnimationLoop);
enqueuedAnimation = "";
enqueuedAnimationLoop = 0;
}
}
@ -1145,7 +1145,7 @@ void SkeletalSprite::deleteBones()
bones.clear();
}
Animation *SkeletalSprite::getAnimation(std::string anim)
Animation *SkeletalSprite::getAnimation(const std::string& anim)
{
for (int i = 0; i < animations.size(); i++)
{
@ -1171,7 +1171,7 @@ void SkeletalSprite::loadSkin(const std::string &fn)
file = core->adjustFilenameCase(file);
if (!exists(file,1))
if (!exists(file))
{
errorLog("Could not load skin[" + file + "]");
return;
@ -1303,6 +1303,7 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
if (!exists(file))
{
filenameLoaded = "";
errorLog("Could not load skeletal[" + file + "]");
return;
}

View file

@ -163,10 +163,10 @@ public:
void updateBones();
void stopAnimation();
float getAnimationLength();
bool createTransitionAnimation(std::string anim, float time);
bool createTransitionAnimation(const std::string& anim, float time);
void playAnimation(int idx, int loop);
void playCurrentAnimation(int loop);
void enqueueAnimation(std::string anim, int loop);
void enqueueAnimation(const std::string& anim, int loop);
float transitionAnimate(std::string anim, float time, int loop);
void setTimeMultiplier(float t);
bool isAnimating();
@ -240,7 +240,7 @@ public:
Animation *getAnimation(std::string anim);
Animation *getAnimation(const std::string& anim);
std::vector<Animation> animations;
std::vector<Bone*> bones;

View file

@ -122,19 +122,10 @@ void StateData::eraseRenderObjects()
for (int i = 0; i < renderObjects.size(); i++)
{
RenderObject *r = renderObjects[i];
//try
if (r && !r->isDead())
{
if (r && !r->isDead())
{
core->enqueueRenderObjectDeletion(renderObjects[i]);
}
core->enqueueRenderObjectDeletion(renderObjects[i]);
}
/*
catch(...)
{
debugLog("Caught exception in StateData::eraseRenderObjects");
}
*/
}
renderObjects.clear();
}
@ -288,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

@ -500,11 +500,18 @@ public:
x = vec.x;
y = vec.y;
z = vec.z;
delete data;
if (vec.data)
data = new InterpolatedVectorData(*vec.data);
{
if (data)
*data = *vec.data;
else
data = new InterpolatedVectorData(*vec.data);
}
else
{
delete data;
data = NULL;
}
return *this;
}

View file

@ -5,7 +5,7 @@ INCLUDE(CheckCCompilerFlag)
INCLUDE(CheckFunctionExists)
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "None Debug Release RelWithDebInfo MinSizeRel" FORCE)
SET(CMAKE_BUILD_TYPE Release CACHE STRING "None Debug Release RelWithDebInfo MinSizeRel" FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
IF(APPLE)
@ -16,6 +16,17 @@ IF(CMAKE_SYSTEM_NAME STREQUAL "Haiku")
SET(HAIKU TRUE)
ENDIF()
IF(WIN32)
SET(WIN32_TRUE TRUE)
ELSE(WIN32)
SET(WIN32_TRUE FALSE)
ENDIF(WIN32)
# if no build type was provided, set a default one
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build (Debug, RelWithDebInfo, Release)" FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
OPTION(AQUARIA_DEVELOPER_BUILD "Developer Build?" FALSE)
OPTION(AQUARIA_DEMO_BUILD "Demo Build?" FALSE)
OPTION(AQUARIA_USE_VFS "Use Virtual File System? Required for some additional features." TRUE)
@ -42,7 +53,7 @@ SET(PNGDIR ${EXTLIBDIR}/glpng/png)
### zlib
OPTION(AQUARIA_INTERNAL_ZLIB "Always use included zlib library" FALSE)
OPTION(AQUARIA_INTERNAL_ZLIB "Always use included zlib library" TRUE)
if(NOT AQUARIA_INTERNAL_ZLIB)
find_package(ZLIB)
endif(NOT AQUARIA_INTERNAL_ZLIB)
@ -52,7 +63,7 @@ endif(NOT ZLIB_FOUND)
### PNG
OPTION(AQUARIA_INTERNAL_PNG "Always use included PNG library" FALSE)
OPTION(AQUARIA_INTERNAL_PNG "Always use included PNG library" TRUE)
if(NOT AQUARIA_INTERNAL_PNG)
find_package(PNG)
endif(NOT AQUARIA_INTERNAL_PNG)
@ -66,7 +77,7 @@ STRING(REGEX REPLACE "^.*PNG_LIBPNG_VER[^0-9]*([0-9]+).*$" "\\1" PNG_LIBPNG_VER
### FreeType
OPTION(AQUARIA_INTERNAL_FREETYPE "Always use included FreeType library" FALSE)
OPTION(AQUARIA_INTERNAL_FREETYPE "Always use included FreeType library" TRUE)
if(NOT AQUARIA_INTERNAL_FREETYPE)
find_package(Freetype)
endif(NOT AQUARIA_INTERNAL_FREETYPE)
@ -76,7 +87,7 @@ endif(NOT FREETYPE_FOUND)
### Lua
OPTION(AQUARIA_INTERNAL_LUA "Always use included Lua library" FALSE)
OPTION(AQUARIA_INTERNAL_LUA "Always use included Lua library" TRUE)
if(NOT AQUARIA_INTERNAL_LUA)
find_package(Lua51)
endif(NOT AQUARIA_INTERNAL_LUA)
@ -86,7 +97,7 @@ endif(NOT LUA51_FOUND)
### Ogg/Vorbis
OPTION(AQUARIA_INTERNAL_OGGVORBIS "Always use included Ogg/Vorbis libraries" FALSE)
OPTION(AQUARIA_INTERNAL_OGGVORBIS "Always use included Ogg/Vorbis libraries" TRUE)
if(NOT AQUARIA_INTERNAL_OGGVORBIS)
# CMake doesn't seem to have a module for libogg or libvorbis yet, so
# we roll our own based on existing find_package modules.
@ -148,7 +159,7 @@ endif(NOT OGGVORBIS_FOUND)
### SDL
OPTION(AQUARIA_INTERNAL_SDL "Always use included SDL library" FALSE)
OPTION(AQUARIA_INTERNAL_SDL "Always use included SDL library" ${WIN32_TRUE})
if(NOT AQUARIA_INTERNAL_SDL)
find_package(SDL)
endif(NOT AQUARIA_INTERNAL_SDL)
@ -172,7 +183,7 @@ endif(NOT SDL_FOUND)
### OpenAL
OPTION(AQUARIA_INTERNAL_OPENAL "Always use included OpenAL library" FALSE)
OPTION(AQUARIA_INTERNAL_OPENAL "Always use included OpenAL library" ${WIN32_TRUE})
if(NOT AQUARIA_INTERNAL_OPENAL)
find_package(OpenAL)
endif(NOT AQUARIA_INTERNAL_OPENAL)
@ -189,19 +200,19 @@ endif (NOT OPENAL_FOUND)
################ End of external libraries
INCLUDE_DIRECTORIES(${BBGEDIR})
INCLUDE_DIRECTORIES(${BBGEDIR}/GL)
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR})
INCLUDE_DIRECTORIES(${SRCDIR})
INCLUDE_DIRECTORIES(${FTGLDIR}/include)
INCLUDE_DIRECTORIES(${FREETYPE_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIR})
INCLUDE_DIRECTORIES(${OGGVORBIS_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR})
INCLUDE_DIRECTORIES(${OPENAL_INCLUDE_DIR})
INCLUDE_DIRECTORIES(${EXTLIBDIR})
INCLUDE_DIRECTORIES(${EXTLIBDIR}/ttvfs)
INCLUDE_DIRECTORIES("${BBGEDIR}")
INCLUDE_DIRECTORIES("${BBGEDIR}/GL")
INCLUDE_DIRECTORIES("${ZLIB_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES("${PNG_INCLUDE_DIR}")
INCLUDE_DIRECTORIES("${SRCDIR}")
INCLUDE_DIRECTORIES("${FTGLDIR}/include")
INCLUDE_DIRECTORIES("${FREETYPE_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES("${LUA_INCLUDE_DIR}")
INCLUDE_DIRECTORIES("${OGGVORBIS_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES("${SDL_INCLUDE_DIR}")
INCLUDE_DIRECTORIES("${OPENAL_INCLUDE_DIR}")
INCLUDE_DIRECTORIES("${EXTLIBDIR}")
INCLUDE_DIRECTORIES("${EXTLIBDIR}/ttvfs")
# Custom build ID: e.g. "-custom", " (my very own build)"
@ -211,6 +222,26 @@ if (NOT(AQUARIA_CUSTOM_BUILD_ID STREQUAL ""))
ADD_DEFINITIONS("-DAQUARIA_CUSTOM_BUILD_ID=\"${AQUARIA_CUSTOM_BUILD_ID}\"")
endif (NOT(AQUARIA_CUSTOM_BUILD_ID STREQUAL ""))
# Custom version string override (displayed as-is instead of "Aquaria vx.x.x ..." on the title screen
SET(AQUARIA_OVERRIDE_VERSION_STRING "" CACHE STRING
"Text to display instead of the Aquaria version ID on the title screen. (Overrides AQUARIA_CUSTOM_BUILD_ID as well)")
if (NOT(AQUARIA_OVERRIDE_VERSION_STRING STREQUAL ""))
ADD_DEFINITIONS("-AQUARIA_OVERRIDE_VERSION_STRING=\"${AQUARIA_OVERRIDE_VERSION_STRING}\"")
endif (NOT(AQUARIA_OVERRIDE_VERSION_STRING STREQUAL ""))
# Custom data directories
SET(AQUARIA_DEFAULT_DATA_DIR "" CACHE STRING
"Default data directory (for package maintainers only)")
if(NOT(AQUARIA_DEFAULT_DATA_DIR STREQUAL ""))
ADD_DEFINITIONS("-DAQUARIA_DEFAULT_DATA_DIR=\"${AQUARIA_DEFAULT_DATA_DIR}\"")
endif(NOT(AQUARIA_DEFAULT_DATA_DIR STREQUAL ""))
SET(AQUARIA_EXTRA_DATA_DIR "" CACHE STRING
"Extra data directory, overrides files from default datadir (for package maintainers only)")
if(NOT(AQUARIA_EXTRA_DATA_DIR STREQUAL ""))
ADD_DEFINITIONS("-DAQUARIA_EXTRA_DATA_DIR=\"${AQUARIA_EXTRA_DATA_DIR}\"")
endif(NOT(AQUARIA_EXTRA_DATA_DIR STREQUAL ""))
# Aquaria/BBGE specific defines...
ADD_DEFINITIONS(-DGL_GLEXT_LEGACY=1)
@ -219,7 +250,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)
@ -276,6 +307,11 @@ IF(CMAKE_COMPILER_IS_GNUCC)
IF(AQUARIA_GCC_HAS_STACKPROT)
ADD_DEFINITIONS(-fno-stack-protector)
ENDIF(AQUARIA_GCC_HAS_STACKPROT)
# -O3 breaks on some GCC/MinGW versions, make sure CMake does not set this as default.
# Exceptions are not used, excluding support for release builds adds less bulk as well.
set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG" CACHE STRING "Flags used for release builds" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG -fno-exceptions" CACHE STRING "Flags used for release builds" FORCE)
# !!! FIXME: probably not safe long-term.
# CMake mailing list had this hack for getting rid of -rdynamic:
@ -348,7 +384,6 @@ SET(AQUARIA_SRCS
${SRCDIR}/SubtitlePlayer.cpp
${SRCDIR}/ToolTip.cpp
${SRCDIR}/UserSettings.cpp
${SRCDIR}/WaterFont.cpp
${SRCDIR}/WaterSurfaceRender.cpp
${SRCDIR}/Web.cpp
${SRCDIR}/WorldMapRender.cpp
@ -361,6 +396,7 @@ SET(AQUARIA_SRCS_UNUSED
${SRCDIR}/BubbleRender.cpp
${SRCDIR}/FFTNotes.cpp
${SRCDIR}/StarRenderer.cpp
${SRCDIR}/WaterFont.cpp
)
IF(MACOSX)
@ -373,7 +409,6 @@ SET(BBGE_SRCS
${BBGEDIR}/ActionMapper.cpp
${BBGEDIR}/ActionSet.cpp
${BBGEDIR}/AfterEffect.cpp
${BBGEDIR}/AnimatedSprite.cpp
${BBGEDIR}/Base.cpp
${BBGEDIR}/BitmapFont.cpp
${BBGEDIR}/Collision.cpp
@ -387,7 +422,6 @@ SET(BBGE_SRCS
${BBGEDIR}/Flags.cpp
${BBGEDIR}/FrameBuffer.cpp
${BBGEDIR}/Gradient.cpp
${BBGEDIR}/Interpolator.cpp
${BBGEDIR}/Joystick.cpp
${BBGEDIR}/LensFlare.cpp
${BBGEDIR}/Localization.cpp
@ -460,12 +494,14 @@ SET(PNG_SRCS
# Apparently not used at the moment. Listed here just for completeness.
SET(BBGE_SRCS_UNUSED
${BBGEDIR}/AnimatedSprite.cpp
${BBGEDIR}/BloomEffect.cpp
${BBGEDIR}/CShim.cpp
${BBGEDIR}/Cutscene.cpp
${BBGEDIR}/Datafile.cpp
${BBGEDIR}/DFSprite.cpp
${BBGEDIR}/FileVars.cpp
${BBGEDIR}/Interpolator.cpp
${BBGEDIR}/Light.cpp
${BBGEDIR}/LightCone.cpp
${BBGEDIR}/Model.cpp
@ -618,12 +654,15 @@ SET(LUA_SRCS
)
IF(AQUARIA_USE_VFS)
ADD_SUBDIRECTORY(${EXTLIBDIR}/ttvfs)
ADD_SUBDIRECTORY(${EXTLIBDIR}/ttvfs_zip)
ADD_SUBDIRECTORY("${EXTLIBDIR}/ttvfs")
ADD_SUBDIRECTORY("${EXTLIBDIR}/ttvfs_zip")
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} "ttvfs")
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} "ttvfs_zip")
ENDIF(AQUARIA_USE_VFS)
IF(WIN32)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} "ws2_32")
ENDIF(WIN32)
IF(MACOSX)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} "-framework Carbon")

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

View file

@ -11,15 +11,15 @@
#include "ByteBuffer.h"
using namespace std;
//OpenGL headers
/*
#ifdef _WINDOWS
#include <windows.h>
#endif
#include <OpenGL/gl.h>
*/
#include "GL/gl.h"
#ifdef _WIN32 /* Stupid Windows needs to include windows.h before gl.h */
#undef FAR
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#undef GetCharWidth
#endif
#include "gl.h"
//glFont header
#include "glfont2.h"
@ -232,7 +232,7 @@ int GLFont::GetCharWidth (unsigned char c)
if (c == ' ' && glfont_char->dx <= 0)
{
GLFontChar *glfont_a = &header.chars['a' - header.start_char];
glfont_char->dx = glfont_a->dx*0.75;
glfont_char->dx = glfont_a->dx*0.75f;
glfont_char->dy = glfont_a->dy;
}

View file

@ -29,6 +29,7 @@
// performance matters, and you implemented actual locking into the Mutex class.
// If no Mutex implementation is provided, its operations are no-ops, beware!
// Note: This adds a *lot* of overhead. Better ensure thread safety yourself, externally. Really!
// (Also note that this feature is *UNTESTED*. Don't activate.)
//#define VFS_THREADSAFE
// By default, ttvfs uses a std::map to store stuff.

View file

@ -394,7 +394,7 @@ unsigned int VFSDirReal::load(bool recursive)
unsigned int sum = li.size();
li.clear();
GetDirList(fullname(), li, false);
GetDirList(fullname(), li, 0);
for(std::deque<std::string>::iterator it = li.begin(); it != li.end(); ++it)
{
// subdir was already present, move over and erase

View file

@ -18,9 +18,9 @@
# include <windows.h>
#else
# ifdef __HAIKU__
# include <dirent.h>
# include <dirent.h>
# else
# include <sys/dir.h>
# include <sys/dir.h>
# endif
# include <unistd.h>
#endif
@ -30,24 +30,12 @@
VFS_NAMESPACE_START
std::string stringToLower(std::string s)
{
std::transform(s.begin(), s.end(), s.begin(), tolower);
return s;
}
std::string stringToUpper(std::string s)
{
std::transform(s.begin(), s.end(), s.begin(), toupper);
return s;
}
void makeLowercase(std::string& s)
void stringToLower(std::string& s)
{
std::transform(s.begin(), s.end(), s.begin(), tolower);
}
void makeUppercase(std::string& s)
void stringToUpper(std::string& s)
{
std::transform(s.begin(), s.end(), s.begin(), toupper);
}
@ -109,7 +97,7 @@ static bool _IsDir(const char *path, dirent *dp)
char *pathname = (char*)alloca(len1 + 1 + len2 + 1 + 13);
strcpy (pathname, path);
/* Avoid UNC-path "//name" on Cygwin. */
/* Avoid UNC-path "//name" on Cygwin. */
if (len1 > 0 && pathname[len1 - 1] != '/')
strcat (pathname, "/");
@ -125,9 +113,9 @@ static bool _IsFile(const char *path, dirent *dp)
{
return !_IsDir(path, dp);
}
#endif
#endif // DT_DIR
#endif
#endif // !_WIN32
// returns list of *plain* file names in given directory,
// without paths, and without anything else
@ -177,7 +165,7 @@ void GetFileList(const char *path, StringList& files)
// returns a list of directory names in the given directory, *without* the source dir.
// if getting the dir list recursively, all paths are added, except *again* the top source dir beeing queried.
void GetDirList(const char *path, StringList &dirs, bool recursive /* = false */)
void GetDirList(const char *path, StringList &dirs, int depth /* = 0 */)
{
#if !_WIN32
DIR * dirp;
@ -185,6 +173,8 @@ void GetDirList(const char *path, StringList &dirs, bool recursive /* = false */
dirp = opendir(path);
if(dirp)
{
std::string pathstr(path);
MakeSlashTerminated(pathstr);
while((dp = readdir(dirp))) // assignment is intentional
{
if (_IsDir(path, dp)) // only add if it is a directory
@ -192,11 +182,13 @@ void GetDirList(const char *path, StringList &dirs, bool recursive /* = false */
if(strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
{
dirs.push_back(dp->d_name);
if (recursive) // needing a better way to do that
if (depth) // needing a better way to do that
{
std::deque<std::string> newdirs;
GetDirList(dp->d_name, newdirs, true);
std::string d(dp->d_name);
std::string d = dp->d_name;
std::string subdir = pathstr + d;
MakeSlashTerminated(d);
StringList newdirs;
GetDirList(subdir.c_str(), newdirs, depth - 1);
for(std::deque<std::string>::iterator it = newdirs.begin(); it != newdirs.end(); ++it)
dirs.push_back(d + *it);
}
@ -207,12 +199,10 @@ void GetDirList(const char *path, StringList &dirs, bool recursive /* = false */
}
#else
std::string search(path);
MakeSlashTerminated(search);
search += "*";
std::string pathstr(path);
MakeSlashTerminated(pathstr);
WIN32_FIND_DATA fil;
HANDLE hFil = FindFirstFile(search.c_str(),&fil);
HANDLE hFil = FindFirstFile((pathstr + '*').c_str(),&fil);
if(hFil != INVALID_HANDLE_VALUE)
{
do
@ -222,14 +212,15 @@ void GetDirList(const char *path, StringList &dirs, bool recursive /* = false */
if (!strcmp(fil.cFileName, ".") || !strcmp(fil.cFileName, ".."))
continue;
std::string d(fil.cFileName);
dirs.push_back(d);
dirs.push_back(fil.cFileName);
if (recursive) // need a better way to do that
if (depth) // need a better way to do that
{
std::string d = fil.cFileName;
std::string subdir = pathstr + d;
MakeSlashTerminated(d);
StringList newdirs;
GetDirList(d.c_str(), newdirs, true);
GetDirList(subdir.c_str(), newdirs, depth - 1);
for(std::deque<std::string>::iterator it = newdirs.begin(); it != newdirs.end(); ++it)
dirs.push_back(d + *it);
}
@ -280,8 +271,10 @@ bool CreateDirRec(const char *dir)
StringList li;
StrSplit(dir, "/\\", li, false);
std::string d;
d.reserve(strlen(dir));
bool last;
d.reserve(strlen(dir) + 1);
if(*dir == '/')
d += '/';
bool last = false;
for(StringList::iterator it = li.begin(); it != li.end(); ++it)
{
d += *it;
@ -407,55 +400,6 @@ std::string StripLastPath(const std::string& s)
return s.substr(0, pos);
}
void GetFileListRecursive(std::string dir, StringList& files, bool withQueriedDir /* = false */)
{
std::stack<std::string> stk;
if(withQueriedDir)
{
stk.push(dir);
while(stk.size())
{
dir = stk.top();
stk.pop();
MakeSlashTerminated(dir);
StringList li;
GetFileList(dir.c_str(), li);
for(std::deque<std::string>::iterator it = li.begin(); it != li.end(); ++it)
files.push_back(dir + *it);
li.clear();
GetDirList(dir.c_str(), li, true);
for(std::deque<std::string>::iterator it = li.begin(); it != li.end(); ++it)
stk.push(dir + *it);
}
}
else
{
std::string topdir = dir;
MakeSlashTerminated(topdir);
stk.push("");
while(stk.size())
{
dir = stk.top();
stk.pop();
MakeSlashTerminated(dir);
StringList li;
dir = topdir + dir;
GetFileList(dir.c_str(), li);
for(std::deque<std::string>::iterator it = li.begin(); it != li.end(); ++it)
files.push_back(dir + *it);
li.clear();
GetDirList(dir.c_str(), li, true);
for(std::deque<std::string>::iterator it = li.begin(); it != li.end(); ++it)
stk.push(dir + *it);
}
}
}
// from http://board.byuu.org/viewtopic.php?f=10&t=1089&start=15
bool WildcardMatch(const char *str, const char *pattern)
{
@ -464,7 +408,8 @@ bool WildcardMatch(const char *str, const char *pattern)
{
if(*pattern != *str && *pattern != '?')
return false;
pattern++, str++;
++pattern;
++str;
}
while(*str)
@ -472,7 +417,7 @@ bool WildcardMatch(const char *str, const char *pattern)
if(*pattern == '*')
{
if(!*++pattern)
return 1;
return true;
mp = pattern;
cp = str + 1;
}
@ -488,7 +433,8 @@ bool WildcardMatch(const char *str, const char *pattern)
}
}
while(*pattern++ == '*');
while(*pattern == '*')
++pattern;
return !*pattern;
}

View file

@ -1,6 +1,9 @@
// VFSTools.h - useful functions and misc stuff
// For conditions of distribution and use, see copyright notice in VFS.h
// Not all of these functions are used by ttvfs, but are added for user convenience.
// Everyone needs some path/file mangling functions at some point.
#ifndef VFS_TOOLS_H
#define VFS_TOOLS_H
@ -13,12 +16,10 @@ VFS_NAMESPACE_START
typedef std::deque<std::string> StringList;
std::string stringToUpper(const std::string& s);
std::string stringToLower(const std::string& s);
void makeUppercase(std::string& s);
void makeLowercase(std::string& s);
void stringToUpper(std::string& s);
void stringToLower(std::string& s);
void GetFileList(const char *, StringList& files);
void GetDirList(const char *, StringList& dirs, bool recursive = false);
void GetDirList(const char *, StringList& dirs, int depth = 0); // recursion depth: 0 = subdirs of current, 1 = subdirs one level down, ..., -1 = deep recursion
bool FileExists(const char *);
bool IsDirectory(const char *);
bool CreateDir(const char*);
@ -30,7 +31,6 @@ const char *PathToFileName(const char *str);
void MakeSlashTerminated(std::string& s);
std::string StripFileExtension(const std::string& s);
std::string StripLastPath(const std::string& s);
void GetFileListRecursive(std::string dir, StringList& files, bool withQueriedDir = false);
bool WildcardMatch(const char *str, const char *pattern);
size_t strnNLcpy(char *dst, const char *src, unsigned int n = -1);
char *fastcat(char *s, const char *add);

View file

@ -163,9 +163,9 @@ const void *VFSFileZip::getBuf(allocator_func alloc /* = NULL */, delete_func de
_delfunc = del;
if(!zip_reader_reopen_vfsfile(_zip, 0))
return false; // can happen if the underlying zip file was deleted
return NULL; // can happen if the underlying zip file was deleted
if(!mz_zip_reader_extract_to_mem(_zip, _zipstat.m_file_index, _buf, sz, 0))
return false; // this should not happen
return NULL; // this should not happen
if(_mode.find("b") == std::string::npos) // text mode?
{

View file

@ -18,6 +18,9 @@ Follow these steps to build Aquaria.
build-essential cmake liblua5.1-0-dev libogg-dev libvorbis-dev
libopenal-dev libsdl1.2-dev
For Lua, libogg, and libvorbis the included versions can be used instead,
thus a system-wide install of these libs is not required.
2- Create a sub-directory 'cmake-build' and move into it
$ mkdir cmake-build
@ -28,6 +31,9 @@ $ cd cmake-build
$ cmake ..
4- If you miss some dependencies, install them and run cmake again.
Due to windows lacking package management, it is recommended
to set all AQUARIA_INTERNAL_* cmake variables to TRUE for win32
builds, or for statically linked linux builds.
5- run make
@ -39,6 +45,7 @@ $ make
$ cp aquaria ~/aquaria/
$ cp -r ../games_scripts/* ~/aquaria
$ cp -r ../files/* ~/aquaria
You should *not* remove any file from the aquaria installation, just
replace some of them with the versions included in this folder.

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

2
game_scripts/scripts/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
vox/*
entities/*.txt

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

@ -32,7 +32,7 @@ v.attackDelay = 0
v.noteQuad = 0
v.holdingNote = false
v.maxHits = 6
v.hits = v.maxHits

View file

@ -223,7 +223,7 @@ function enterState(me)
bone_rotate(v.glow, 0, 1, 0, 0, 1)
bone_rotate(v.glow, 360, 1, -1)
end
bone_rotate(v.boneNote, -entity_getRotation(me))
bone_rotate(v.noteBone, -entity_getRotation(me))
end
function exitState(me)

View file

@ -132,15 +132,17 @@ function update(me, dt)
if entity_hasTarget(me) then
target = entity_getTarget(me)
--[[
ox, oy = entity_getOffset(target)
cx = entity_x(target) + ox + entity_velx(target)
cy = entity_y(target) + oy + entity_vely(target)
]]--
cx, cy = entity_getTargetPoint(target, v.tpoint)
cx = cx + entity_velx(target)
cy = cy + entity_vely(target)
dist = 40
if target ~= 0 then
--[[
ox, oy = entity_getOffset(target)
cx = entity_x(target) + ox + entity_velx(target)
cy = entity_y(target) + oy + entity_vely(target)
]]--
cx, cy = entity_getTargetPoint(target, v.tpoint)
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
entity_flipToEntity(me, target)
entity_rotateToEntity(me, target)
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

@ -200,14 +200,6 @@
RelativePath="..\..\BBGE\AfterEffect.h"
>
</File>
<File
RelativePath="..\..\BBGE\AnimatedSprite.cpp"
>
</File>
<File
RelativePath="..\..\BBGE\AnimatedSprite.h"
>
</File>
<File
RelativePath="..\..\BBGE\Base.cpp"
>
@ -316,14 +308,6 @@
RelativePath="..\..\BBGE\Gradient.h"
>
</File>
<File
RelativePath="..\..\BBGE\Interpolator.cpp"
>
</File>
<File
RelativePath="..\..\BBGE\Interpolator.h"
>
</File>
<File
RelativePath="..\..\BBGE\Joystick.cpp"
>
@ -368,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"
>