diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index a4c030f..dd2cb05 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -120,6 +120,12 @@ const float NOTE_ACCEPT_ANGLE_OFFSET = 15; const int COLLIDE_RADIUS_NORMAL = 10; const int COLLIDE_RADIUS_FISH = 8; +const int COLLIDE_RANGE_NORMAL = 2; +const int COLLIDE_RANGE_FISH = 1; + +const float COLLIDE_MOD_NORMAL = 1.0f; +const float COLLIDE_MOD_FISH = 0.1f; + const int requiredDualFormCharge = 3; bool usingDigital = false; @@ -744,7 +750,7 @@ void Avatar::toggleMovement(bool on) bool Avatar::isLockable() { - return (bursting || !_isUnderWater) && (boneLockDelay == 0) && (dsq->continuity.form != FORM_FISH); + return (bursting || !_isUnderWater) && (boneLockDelay == 0) && canLockToWall(); } bool Avatar::isSinging() @@ -752,11 +758,6 @@ bool Avatar::isSinging() return singing; } -void Avatar::shift() -{ - dsq->continuity.shiftWorlds(); -} - void Avatar::applyWorldEffects(WorldType type) { static bool oldfh=false; @@ -1595,6 +1596,8 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF //rotationOffset.interpolateTo(Vector(0,0,0), 0.5); collideRadius = COLLIDE_RADIUS_NORMAL; + setCanLockToWall(true); + setCollisionAvoidanceData(COLLIDE_RANGE_NORMAL, COLLIDE_MOD_NORMAL); } break; case FORM_SUN: @@ -1606,9 +1609,13 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF position = bodyPosition; dsq->continuity.warpLiToAvatar(); spiritBeaconEmitter.start(); + setCanActivateStuff(true); + setCanLockToWall(true); + setCanBurst(true); + setDamageTarget(DT_WALLHURT, true); break; case FORM_BEAST: - //dsq->game->sceneColor3.interpolateTo(Vector(1, 1, 1), 0.5); + setCanSwimAgainstCurrents(false); break; case FORM_DUAL: if (dsq->continuity.hasLi()) @@ -1618,6 +1625,9 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF dsq->game->li->setState(STATE_IDLE); } break; + case FORM_NATURE: + setDamageTarget(DT_WALLHURT, true); + break; default: if (leftHandEmitter && rightHandEmitter) { @@ -1727,6 +1737,8 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF //refreshModel("NaijaFish", ""); collideRadius = COLLIDE_RADIUS_FISH; + setCanLockToWall(false); + setCollisionAvoidanceData(COLLIDE_RANGE_FISH, COLLIDE_MOD_FISH); } break; case FORM_SUN: @@ -1758,42 +1770,13 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF hair->setTexture("Naija/Cape-NatureForm"); hair->alphaMod = 1.0; } - /* - skeletalSprite.loadSkin("ChildTeira"); - refreshModel(); - */ - /* - if (dsq->game->sceneNatureForm == "forest") - { - debugLog("Forest Form"); - dsq->continuity.form = FORM_NATURE_FOREST; - } - else if (dsq->game->sceneNatureForm == "sun") - { - dsq->continuity.form = FORM_NATURE_SUN; - debugLog("Sun Form"); - } - else if (dsq->game->sceneNatureForm == "fire") - { - dsq->continuity.form = FORM_NATURE_FIRE; - debugLog("Fire Form"); - } - else if (dsq->game->sceneNatureForm == "dark") - { - dsq->continuity.form = FORM_NATURE_DARK; - debugLog("Dark Form"); - } - else if (dsq->game->sceneNatureForm == "rock" || dsq->game->sceneNatureForm.empty()) - { - dsq->continuity.form = FORM_NATURE_ROCK; - debugLog("Rock Form"); - } - */ + setDamageTarget(DT_WALLHURT, false); break; case FORM_BEAST: { refreshModel("Naija", "BeastForm"); + setCanSwimAgainstCurrents(true); } break; case FORM_SPIRIT: @@ -1801,6 +1784,10 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF bodyOffset = offset; fallOffWall(); dsq->continuity.shiftWorlds(); + setCanActivateStuff(false); + setCanLockToWall(false); + setCanBurst(false); + setDamageTarget(DT_WALLHURT, false); if (onInit) { @@ -3495,8 +3482,8 @@ void Avatar::lockToWallCommon() void Avatar::lockToWall() { if (riding) return; - if (inCurrent && dsq->continuity.form != FORM_BEAST) return; - if (dsq->continuity.form == FORM_FISH || dsq->continuity.form == FORM_SPIRIT) return; + if (inCurrent && !canSwimAgainstCurrents()) return; + if (!canLockToWall()) return; if (state.lockedToWall) return; if (vel.x == 0 && vel.y == 0) return; if (dsq->game->isPaused()) return; @@ -3594,7 +3581,7 @@ void Avatar::lockToWall() } } - if (dsq->game->getGrid(t)==OT_HURT && dsq->continuity.form != FORM_NATURE) + if (dsq->game->getGrid(t)==OT_HURT && isDamageTarget(DT_WALLHURT)) { good = false; } @@ -4128,6 +4115,18 @@ Avatar::Avatar() : Entity(), ActionMapper() collideRadius = COLLIDE_RADIUS_FISH; else collideRadius = COLLIDE_RADIUS_NORMAL; + + // defaults for normal form + _canActivateStuff = true; + _canBurst = true; + _canLockToWall = true; + _canSwimAgainstCurrents = false; + _canCollideWithShots = true; + + _collisionAvoidMod = COLLIDE_MOD_NORMAL; + _collisionAvoidRange = COLLIDE_RANGE_NORMAL; + + _seeMapMode = SEE_MAP_DEFAULT; } void Avatar::revert() @@ -4324,7 +4323,7 @@ void Avatar::startBurstCommon() void Avatar::startBurst() { - if (!riding && dsq->continuity.form != FORM_SPIRIT && (joystickMove || getVectorToCursor().getSquaredLength2D() > sqr(BURST_DISTANCE)) + if (!riding && canBurst() && (joystickMove || getVectorToCursor().getSquaredLength2D() > sqr(BURST_DISTANCE)) && getState() != STATE_PUSH && (!skeletalSprite.getCurrentAnimation() || (skeletalSprite.getCurrentAnimation()->name != "spin")) && _isUnderWater && !isActing(ACTION_ROLL)) { @@ -4686,6 +4685,35 @@ void Avatar::action(int id, int state) } } +void Avatar::doBindSong() +{ + if (pullTarget) + { + pullTarget->stopPull(); + pullTarget = 0; + core->sound->playSfx("Denied"); + } + else + { + dsq->game->bindIngredients(); + setNearestPullTarget(); + if (!pullTarget) + { + core->sound->playSfx("Denied"); + } + else + { + core->sound->playSfx("Bind"); + } + } +} + +void Avatar::doShieldSong() +{ + core->sound->playSfx("Shield-On"); + activateAura(AURA_SHIELD); +} + void Avatar::render() { @@ -4858,10 +4886,6 @@ void Avatar::clampVelocity() } } - - - - if (!inCurrent || (inCurrent && withCurrent)) { if (dsq->continuity.form == FORM_FISH) @@ -5246,7 +5270,7 @@ void Avatar::updateWallJump(float dt) void Avatar::updateRoll(float dt) { - if (!inputEnabled || dsq->continuity.getWorldType() == WT_SPIRIT) + if (!inputEnabled || dsq->game->isWorldPaused()) { if (rolling) stopRoll(); @@ -5385,7 +5409,18 @@ void Avatar::setWasUnderWater() bool Avatar::canActivateStuff() { - return dsq->continuity.form != FORM_SPIRIT; + return _canActivateStuff; +} + +void Avatar::setCanActivateStuff(bool on) +{ + _canActivateStuff = on; +} + +void Avatar::setCollisionAvoidanceData(int range, float mod) +{ + _collisionAvoidRange = range; + _collisionAvoidMod = mod; } bool Avatar::canQuickSong() @@ -6176,7 +6211,7 @@ void Avatar::onUpdate(float dt) //if (core->getNestedMains() == 1) { - if (getState() != STATE_TRANSFORM && dsq->continuity.getWorldType() == WT_NORMAL) + if (getState() != STATE_TRANSFORM && !dsq->game->isWorldPaused()) { formAbilityUpdate(dt); } @@ -6410,7 +6445,7 @@ void Avatar::onUpdate(float dt) } } - if (!state.lockedToWall && _isUnderWater && dsq->continuity.getWorldType() == WT_NORMAL && canMove) + if (!state.lockedToWall && _isUnderWater && !dsq->game->isWorldPaused() && canMove) { if (bursting) { @@ -7054,13 +7089,9 @@ void Avatar::onUpdate(float dt) } - if (!state.lockedToWall && !bursting && _isUnderWater && swimming && !isFollowingPath()) + if (!state.lockedToWall && !bursting && _isUnderWater && swimming && !isFollowingPath() && _collisionAvoidRange > 0) { - //debugLog("collision avoidance"); - if (dsq->continuity.form == FORM_FISH) - doCollisionAvoidance(dt, 1, 0.1, 0, 800, OT_HURT); - else - doCollisionAvoidance(dt, 2, 1.0, 0, 800, OT_HURT); + doCollisionAvoidance(dt, _collisionAvoidRange, _collisionAvoidMod, 0, 800, OT_HURT); } if (!game->isShuttingDownGameState()) @@ -7118,7 +7149,6 @@ void Avatar::onUpdate(float dt) else omov -= mov; - lastLastPosition = position; lastPosition = position; Vector newPosition = position + mov; //Vector testPosition = position + (vel *dt)*2; @@ -7127,11 +7157,11 @@ void Avatar::onUpdate(float dt) if (dsq->game->collideCircleWithGrid(position, collideRadius)) { if (dsq->game->lastCollideTileType == OT_HURT - && dsq->continuity.getWorldType() != WT_SPIRIT - && dsq->continuity.form != FORM_NATURE) + && isDamageTarget(DT_WALLHURT)) { DamageData d; d.damage = 1; + d.damageType = DT_WALLHURT; damage(d); vel2 = Vector(0,0,0); //doCollisionAvoidance(1, 3, 1); @@ -7294,7 +7324,8 @@ void Avatar::onUpdate(float dt) rightHandEmitter->position = boneRightHand->getWorldCollidePosition(Vector(0,16)); } - dsq->game->handleShotCollisions(this, (activeAura == AURA_SHIELD)); + if(canCollideWithShots()) + dsq->game->handleShotCollisions(this, (activeAura == AURA_SHIELD)); } @@ -7314,7 +7345,7 @@ void Avatar::checkNearWall() { t.x = oT.x + v.x*i; t.y = oT.y + v.y*i; - if (dsq->game->isObstructed(t) && dsq->game->getGrid(t) != OT_HURT) + if (dsq->game->isObstructed(t, ~OT_HURT)) { obs = true; break; diff --git a/Aquaria/Avatar.h b/Aquaria/Avatar.h index 0b8a196..dea3095 100644 --- a/Aquaria/Avatar.h +++ b/Aquaria/Avatar.h @@ -66,6 +66,13 @@ enum AvatarAnimLayers ANIMLAYER_MAX }; +enum SeeMapMode +{ + SEE_MAP_NEVER = 0, + SEE_MAP_DEFAULT = 1, + SEE_MAP_ALWAYS = 2, +}; + class SongIconParticle : public Quad { public: @@ -160,7 +167,6 @@ public: Entity *entityToActivate; Path *pathToActivate; - void shift(); void applyWorldEffects(WorldType type); void toggleMovement(bool on); @@ -284,6 +290,7 @@ public: void endOfGameState(); bool canQuickSong(); bool canActivateStuff(); + void setCanActivateStuff(bool on); bool hasThingToActivate(); float biteTimer; @@ -317,6 +324,25 @@ 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; @@ -450,7 +476,15 @@ protected: void lockToWall(); void doShock(const std::string &shotName); - Vector lastLastPosition; + bool _canActivateStuff; + bool _canBurst; + bool _canLockToWall; + bool _canSwimAgainstCurrents; + bool _canCollideWithShots; + SeeMapMode _seeMapMode; + + int _collisionAvoidRange; + float _collisionAvoidMod; }; diff --git a/Aquaria/Beam.cpp b/Aquaria/Beam.cpp index 003fc7b..00dd262 100644 --- a/Aquaria/Beam.cpp +++ b/Aquaria/Beam.cpp @@ -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(); diff --git a/Aquaria/Continuity.cpp b/Aquaria/Continuity.cpp index 063dd8a..18ee693 100644 --- a/Aquaria/Continuity.cpp +++ b/Aquaria/Continuity.cpp @@ -1347,16 +1347,6 @@ Song *Continuity::getSongByIndex(int idx) return &songBank[idx]; } -int Continuity::getSongBankSize() -{ - int c = 0; - for (SongMap::iterator i = songBank.begin(); i != songBank.end(); i++) - { - c++; - } - return c; -} - void Continuity::castSong(int num) { if (!dsq->continuity.hasSong((SongType)num)) return; @@ -1409,32 +1399,10 @@ void Continuity::castSong(int num) switch((SongType)num) { case SONG_SHIELDAURA: - core->sound->playSfx("Shield-On"); - dsq->game->avatar->activateAura(AURA_SHIELD); + dsq->game->avatar->doShieldSong(); break; case SONG_BIND: - //debugLog("sang pull"); - if (dsq->game->avatar->pullTarget) - { - dsq->game->avatar->pullTarget->stopPull(); - dsq->game->avatar->pullTarget = 0; - core->sound->playSfx("Denied"); - } - else - { - dsq->game->bindIngredients(); - dsq->game->avatar->setNearestPullTarget(); - if (!dsq->game->avatar->pullTarget) - { - core->sound->playSfx("Denied"); - } - else - { - core->sound->playSfx("Bind"); - } - } - //dsq->game->avatar->openPullTargetInterface(); - //pickingPullTarget = true; + dsq->game->avatar->doBindSong(); break; case SONG_ENERGYFORM: dsq->game->avatar->changeForm(FORM_ENERGY); @@ -1948,9 +1916,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; diff --git a/Aquaria/CurrentRender.cpp b/Aquaria/CurrentRender.cpp index 7118480..fd40034 100644 --- a/Aquaria/CurrentRender.cpp +++ b/Aquaria/CurrentRender.cpp @@ -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; diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index bc4fff4..99427b2 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -1532,10 +1532,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); @@ -4564,6 +4564,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 @@ -4576,6 +4580,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); @@ -4590,7 +4595,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(); diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 5043f36..e24d4ff 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -996,7 +996,6 @@ public: FormUpgrades formUpgrades; void loadSongBank(); - int getSongBankSize(); void loadIntoSongBank(const std::string &file); int checkSong(const Song &song); int checkSongAssisted(const Song &song); diff --git a/Aquaria/Entity.cpp b/Aquaria/Entity.cpp index 8e7f027..e394019 100644 --- a/Aquaria/Entity.cpp +++ b/Aquaria/Entity.cpp @@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "ScriptedEntity.h" #include "Shot.h" -Shader Entity::blurShader; +//Shader Entity::blurShader; void Entity::stopPull() { @@ -1080,7 +1080,7 @@ void Entity::onFHScale() copySkel.alpha.interpolateTo(0, 0.5); */ //skeletalSprite.alpha.interpolateTo(1,sct); - blurShaderAnim.interpolateTo(Vector(blurMin,0,0), sct); + //blurShaderAnim.interpolateTo(Vector(blurMin,0,0), sct); fhScale = 0; } @@ -1105,8 +1105,8 @@ void Entity::onFH() flipScale.interpolateTo(Vector(0.6, 1), sct); - blurShaderAnim = Vector(blurMin); - blurShaderAnim.interpolateTo(Vector(blurMax,0,0), sct/2); + //blurShaderAnim = Vector(blurMin); + //blurShaderAnim.interpolateTo(Vector(blurMax,0,0), sct/2); fhScale = 1; } @@ -1142,9 +1142,9 @@ void Entity::update(float dt) if (doUpdate && !dsq->game->isPaused()) { - if (getEntityType() == ET_ENEMY || getEntityType() == ET_NEUTRAL || getEntityType() == ET_PET) + if (!(getEntityType() == ET_AVATAR || getEntityType() == ET_INGREDIENT)) { - if (spiritFreeze && dsq->continuity.getWorldType() == WT_SPIRIT) + if (spiritFreeze && dsq->game->isWorldPaused()) { // possible bug here because of return return; @@ -1382,7 +1382,7 @@ bool Entity::updateCurrents(float dt) // why? { //Path *p = dsq->game->getNearestPath(position, PATH_CURRENT); - if (dsq->continuity.getWorldType() != WT_SPIRIT) + if (!dsq->game->isWorldPaused()) { for (Path *p = dsq->game->getFirstPathOfType(PATH_CURRENT); p; p = p->nextOfType) { @@ -1419,7 +1419,7 @@ bool Entity::updateCurrents(float dt) float useLen = len; if (useLen < 500) useLen = 500; - if (!(this->getEntityType() == ET_AVATAR && dsq->continuity.form == FORM_BEAST && dsq->game->avatar->bursting)) + if (!(this->getEntityType() == ET_AVATAR && dsq->game->avatar->canSwimAgainstCurrents() && dsq->game->avatar->bursting)) { doCollisionAvoidance(1, 4, 1, &vel2, useLen); } @@ -1439,7 +1439,7 @@ bool Entity::updateCurrents(float dt) } } } - if (this->getEntityType() == ET_AVATAR && dsq->continuity.form == FORM_BEAST) + if (this->getEntityType() == ET_AVATAR && dsq->game->avatar->canSwimAgainstCurrents()) { int cap = 100; if (!vel.isZero()) @@ -1681,7 +1681,7 @@ void Entity::onUpdate(float dt) break; } - blurShaderAnim.update(dt); + //blurShaderAnim.update(dt); } @@ -2832,23 +2832,18 @@ void Entity::render() // HACK: need to multiply base + etc skeletalSprite.setColorMult(this->color, this->alpha.x); - bool set=false; + /*bool set=false; if (beautyFlip && blurShader.isLoaded() && flipScale.isInterpolating() && dsq->user.video.blur) { - /* - std::ostringstream os; - os << "blurShaderAnim: " << blurShaderAnim.x; - debugLog(os.str()); - */ //swizzle blurShader.setValue(color.x, color.y, color.z, blurShaderAnim.x); blurShader.bind(); set = true; - } + }*/ Quad::render(); //if (beautyFlip && blurShader.isLoaded() && flipScale.isInterpolating()) - if (set) - blurShader.unbind(); + //if (set) + // blurShader.unbind(); renderBorder = false; skeletalSprite.clearColorMult(); color = bcolor; @@ -3133,3 +3128,14 @@ void Entity::exertHairForce(const Vector &force, float dt) } } +bool Entity::isEntityInside() +{ + FOR_ENTITIES(i) + { + Entity *e = *i; + if (e && e->life == 1 && e != this && e->ridingOnEntity != this && isCoordinateInside(e->position)) + return true; + + } + return false; +} diff --git a/Aquaria/Entity.h b/Aquaria/Entity.h index 336ccf3..70c7a51 100644 --- a/Aquaria/Entity.h +++ b/Aquaria/Entity.h @@ -123,6 +123,7 @@ enum DamageType DT_CRUSH = 1032, DT_SPIKES = 1033, DT_STEAM = 1034, + DT_WALLHURT = 1035, DT_REALMAX }; @@ -436,6 +437,7 @@ public: void setDieTimer(float v) { dieTimer = v; } float getHealthPerc(); void setDeathScene(bool v); + bool isDeathScene() const { return deathScene; } void generateCollisionMask(int ovrCollideRadius=0); DamageData lastDamage; bool checkSplash(const Vector &override=Vector(0,0,0)); @@ -450,7 +452,7 @@ public: //bool registerEntityDied; bool clampToSurface(int tcheck=0, Vector usePos=Vector(0,0), TileVector hitTile=TileVector(0,0)); bool checkSurface(int tcheck, int state, float statet); - static Shader blurShader; + //static Shader blurShader; std::string naijaReaction; Vector lookAtPoint; Vector getLookAtPoint(); @@ -488,6 +490,8 @@ public: void setHairHeadPosition(const Vector &pos); void exertHairForce(const Vector &force, float dt); + bool isEntityInside(); + protected: bool calledEntityDied; Path *waterBubble; @@ -514,7 +518,7 @@ protected: int lance; Bone *lanceBone; void updateLance(float dt); - InterpolatedVector blurShaderAnim; + //InterpolatedVector blurShaderAnim; int fhScale, fvScale; diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index cab97ab..733399b 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -1233,6 +1233,8 @@ Game::Game() : StateObject() loadEntityTypeList(); + lastCollideMaskIndex = -1; + worldPaused = false; } @@ -5717,7 +5719,7 @@ void Game::updateParticlePause() { core->particlesPaused = 2; } - else if (dsq->continuity.getWorldType() == WT_SPIRIT) + else if (this->isWorldPaused()) { core->particlesPaused = 1; } @@ -8356,7 +8358,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; } @@ -8367,24 +8369,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) @@ -9977,7 +9972,7 @@ void Game::update(float dt) if (avatar) { - tintColor.update(dt); + /*tintColor.update(dt); if (core->afterEffectManager) { if (tintColor.isInterpolating()) @@ -9986,7 +9981,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)); diff --git a/Aquaria/Game.h b/Aquaria/Game.h index 33a5bc6..d9c103e 100644 --- a/Aquaria/Game.h +++ b/Aquaria/Game.h @@ -892,7 +892,8 @@ public: std::string getNoteName(int n, const std::string &pre=""); void selectEntityFromGroups(); - InterpolatedVector cameraInterp, tintColor; + InterpolatedVector cameraInterp; + //InterpolatedVector tintColor; float getWaterLevel(); void setMusicToPlay(const std::string &musicToPlay); Vector lastCollidePosition; @@ -1001,6 +1002,9 @@ public: void toggleHelpScreen(bool on, const std::string &label=""); void onToggleHelpScreen(); + void setWorldPaused(bool b) { worldPaused = b; } + bool isWorldPaused() const { return worldPaused; } + protected: void onHelpUp(); @@ -1158,6 +1162,7 @@ protected: std::vector 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); diff --git a/Aquaria/Hair.cpp b/Aquaria/Hair.cpp index 69200da..80cc0f0 100644 --- a/Aquaria/Hair.cpp +++ b/Aquaria/Hair.cpp @@ -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 } diff --git a/Aquaria/Ingredient.cpp b/Aquaria/Ingredient.cpp index d31d980..97b9e42 100644 --- a/Aquaria/Ingredient.cpp +++ b/Aquaria/Ingredient.cpp @@ -109,7 +109,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); diff --git a/Aquaria/MiniMapRender.cpp b/Aquaria/MiniMapRender.cpp index 095db91..77e6668 100644 --- a/Aquaria/MiniMapRender.cpp +++ b/Aquaria/MiniMapRender.cpp @@ -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) { diff --git a/Aquaria/Mod.cpp b/Aquaria/Mod.cpp index 693b9f0..beac053 100644 --- a/Aquaria/Mod.cpp +++ b/Aquaria/Mod.cpp @@ -284,6 +284,7 @@ void Mod::stop() debugMenu = false; shuttingDown = false; dsq->scriptInterface.reset(); + dsq->game->setWorldPaused(false); } void Mod::update(float dt) diff --git a/Aquaria/Path.cpp b/Aquaria/Path.cpp index 41da549..400d4b4 100644 --- a/Aquaria/Path.cpp +++ b/Aquaria/Path.cpp @@ -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; diff --git a/Aquaria/Path.h b/Aquaria/Path.h index b3369a2..8087008 100644 --- a/Aquaria/Path.h +++ b/Aquaria/Path.h @@ -143,6 +143,7 @@ public: std::string gem; bool effectOn; + bool spiritFreeze; PathShape pathShape; diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 0714f94..c4517ea 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -361,7 +361,7 @@ static void scriptError(lua_State *L, const std::string& msg) // - The C++ standard allows offsetof() only on POD-types. Oh well, it probably works anyways. // If it does not compile for some reason, comment it out, hope for the best, and go ahead. #if !(defined(__GNUC__) && __GNUC__ <= 2) -void compile_time_assertions() +static void compile_time_assertions() { #define oo(cls) offsetof(cls, _objtype) compile_assert(oo(Path) == oo(RenderObject)); @@ -377,6 +377,8 @@ void compile_time_assertions() compile_assert(oo(Path) == oo(Quad)); compile_assert(oo(Path) == oo(Avatar)); compile_assert(oo(Path) == oo(BaseText)); + compile_assert(oo(Path) == oo(PauseQuad)); + compile_assert(oo(Path) == oo(Shader)); #undef oo } #endif @@ -457,6 +459,12 @@ std::string getString(lua_State *L, int slot = 1) return sr; } +static inline +const char *getCString(lua_State *L, int slot = 1) +{ + return lua_isstring(L, slot) ? lua_tostring(L, slot) : NULL; +} + static inline Shot *getShot(lua_State *L, int slot = 1) { @@ -578,6 +586,16 @@ BaseText *getText(lua_State *L, int slot = 1) return q; } +static inline +Shader *getShader(lua_State *L, int slot = 1) +{ + Shader *q = (Shader*)lua_touserdata(L, slot); + ENSURE_TYPE(q, SCO_SHADER); + if (!q) + scriptDebug(L, "Invalid Shader"); + return q; +} + static SkeletalSprite *getSkeletalSprite(Entity *e) { return e ? &e->skeletalSprite : NULL; @@ -1579,6 +1597,7 @@ luaFunc(quad_setSegs) RO_FUNC(getter, prefix, disableMotionBlur ) \ RO_FUNC(getter, prefix, collideCircleVsLine) \ RO_FUNC(getter, prefix, collideCircleVsLineAngle) \ + RO_FUNC(getter, prefix, getVectorToObj ) \ MK_ALIAS(prefix, fh, flipHorizontal ) \ MK_ALIAS(prefix, fv, flipVertical ) @@ -2112,18 +2131,22 @@ luaFunc(entity_setRidingData) luaFunc(entity_setBoneLock) { Entity *e = entity(L); - Entity *e2 = entity(L, 2); - Bone *b = 0; - if (lua_isuserdata(L, 3)) - b = bone(L, 3); bool ret = false; if (e) { BoneLock bl; - bl.entity = e2; - bl.bone = b; - bl.on = true; - bl.collisionMaskIndex = dsq->game->lastCollideMaskIndex; + if (lua_isuserdata(L, 2)) + { + Entity *e2 = entity(L, 2); + Bone *b = 0; + if (lua_isuserdata(L, 3)) + b = bone(L, 3); + + bl.entity = e2; + bl.bone = b; + bl.on = true; + bl.collisionMaskIndex = dsq->game->lastCollideMaskIndex; + } ret = e->setBoneLock(bl); } luaReturnBool(ret); @@ -2347,6 +2370,25 @@ luaFunc(getWorldType) luaReturnNum((int)dsq->continuity.getWorldType()); } +luaFunc(setWorldType) +{ + WorldType wt = (WorldType)lua_tointeger(L, 1); + bool trans = getBool(L, 2); + dsq->continuity.applyWorldEffects(wt, trans, 1); // last arg is not used + luaReturnNil(); +} + +luaFunc(isWorldPaused) +{ + luaReturnBool(dsq->game->isWorldPaused()); +} + +luaFunc(setWorldPaused) +{ + dsq->game->setWorldPaused(getBool(L, 1)); + luaReturnNil(); +} + luaFunc(getNearestNodeByType) { int x = lua_tonumber(L, 1); @@ -2542,6 +2584,14 @@ luaFunc(entity_setSpiritFreeze) luaReturnNil(); } +luaFunc(node_setSpiritFreeze) +{ + Path *e = path(L); + if (e) + e->spiritFreeze = getBool(L,2); + luaReturnNil(); +} + luaFunc(entity_setFillGrid) { Entity *e = entity(L); @@ -2553,6 +2603,12 @@ luaFunc(entity_setFillGrid) luaReturnNil(); } +luaFunc(entity_isFillGrid) +{ + Entity *e = entity(L); + luaReturnBool(e ? e->fillGridFromQuad : false); +} + luaFunc(entity_getAimVector) { Entity *e = entity(L); @@ -2679,6 +2735,69 @@ luaFunc(avatar_setCanDie) luaReturnNil(); } +// not naming this avatar_* because it rather belongs into the UI category... +luaFunc(setCanActivate) +{ + dsq->game->avatar->setCanActivateStuff(getBool(L, 1)); + luaReturnNil(); +} + +luaFunc(setSeeMapMode) +{ + dsq->game->avatar->setSeeMapMode((SeeMapMode)lua_tointeger(L, 1)); + luaReturnNil(); +} + +luaFunc(avatar_setCanBurst) +{ + dsq->game->avatar->setCanBurst(getBool(L, 1)); + luaReturnNil(); +} + +luaFunc(avatar_canBurst) +{ + luaReturnBool(dsq->game->avatar->canBurst()); +} + +luaFunc(avatar_setCanLockToWall) +{ + dsq->game->avatar->setCanBurst(getBool(L, 1)); + luaReturnNil(); +} + +luaFunc(avatar_canLockToWall) +{ + luaReturnBool(dsq->game->avatar->canBurst()); +} + +luaFunc(avatar_setCanSwimAgainstCurrents) +{ + dsq->game->avatar->setCanSwimAgainstCurrents(getBool(L, 1)); + luaReturnNil(); +} + +luaFunc(avatar_canSwimAgainstCurrents) +{ + luaReturnBool(dsq->game->avatar->canSwimAgainstCurrents()); +} + +luaFunc(avatar_setCanCollideWithShots) +{ + dsq->game->avatar->setCollideWithShots(getBool(L, 1)); + luaReturnNil(); +} + +luaFunc(avatar_canCollideWithShots) +{ + luaReturnBool(dsq->game->avatar->canCollideWithShots()); +} + +luaFunc(avatar_setCollisionAvoidanceData) +{ + dsq->game->avatar->setCollisionAvoidanceData(lua_tointeger(L, 1), lua_tonumber(L, 2)); + luaReturnNil(); +} + luaFunc(avatar_toggleCape) { dsq->game->avatar->toggleCape(getBool(L,1)); @@ -2693,6 +2812,11 @@ luaFunc(avatar_setBlockSinging) luaReturnNil(); } +luaFunc(avatar_isBlockSinging) +{ + luaReturnBool(dsq->game->avatar->isBlockSinging()); +} + luaFunc(avatar_fallOffWall) { dsq->game->avatar->fallOffWall(); @@ -2726,6 +2850,16 @@ luaFunc(avatar_isShieldActive) luaReturnBool(v); } +luaFunc(avatar_setShieldActive) +{ + bool on = getBool(L, 1); + if (on) + dsq->game->avatar->activateAura(AURA_SHIELD); + else + dsq->game->avatar->stopAura(); + luaReturnNil(); +} + luaFunc(avatar_getStillTimer) { luaReturnNum(dsq->game->avatar->stillTimer.getValue()); @@ -3741,6 +3875,12 @@ luaFunc(setSceneColor) luaReturnNil(); } +luaFunc(getSceneColor) +{ + const Vector& c = dsq->game->sceneColor3; + luaReturnVec3(c.x, c.y, c.z); +} + luaFunc(setCameraLerpDelay) { dsq->game->cameraLerpDelay = lua_tonumber(L, 1); @@ -4577,6 +4717,18 @@ luaFunc(entity_getDistanceToTarget) luaReturnNum(dist); } +luaFunc(entity_getDistanceToPoint) +{ + Entity *e = entity(L); + float dist = 0; + if (e) + { + Vector p(lua_tonumber(L, 2), lua_tonumber(L, 3)); + dist = (p - e->position).getLength2D(); + } + luaReturnNum(dist); +} + luaFunc(entity_watchEntity) { Entity *e = entity(L); @@ -4731,6 +4883,15 @@ luaFunc(createQuad) luaReturnPtr(q); } +luaFunc(quad_setPauseLevel) +{ + Quad *q = getQuad(L); + ENSURE_TYPE(q, SCO_PAUSEQUAD); + if (q) + ((PauseQuad*)q)->pauseLevel = lua_tointeger(L, 2); + luaReturnNil(); +} + luaFunc(setupEntity) { ScriptedEntity *se = scriptedEntity(L); @@ -5045,6 +5206,12 @@ luaFunc(entity_setMaxSpeedLerp) luaReturnNil(); } +luaFunc(entity_getMaxSpeedLerp) +{ + Entity *e = entity(L); + luaReturnNum(e ? e->maxSpeedLerp.x : 0.0f); +} + // note: this is a weaker setState than perform // this is so that things can override it // for example getting PUSH-ed (Force) or FROZEN (bubbled) @@ -5217,6 +5384,12 @@ luaFunc(entity_setDeathScene) luaReturnNil(); } +luaFunc(entity_isDeathScene) +{ + Entity *e = entity(L); + luaReturnBool(e ? e->isDeathScene() : false); +} + luaFunc(entity_setCurrentTarget) { Entity *e = entity(L); @@ -6155,6 +6328,12 @@ luaFunc(entity_getDistanceToEntity) luaReturnNum(d); } +luaFunc(entity_isEntityInside) +{ + Entity *e = entity(L); + luaReturnBool(e ? e->isEntityInside() : false); +} + // entity_istargetInRange luaFunc(entity_isTargetInRange) { @@ -6559,6 +6738,20 @@ luaFunc(entity_getNearestEntity) luaReturnPtr(closest); } +luaFunc(getNearestEntity) +{ + Vector p(lua_tonumber(L, 1), lua_tonumber(L, 2)); + int radius = lua_tointeger(L, 3); + Entity *ignore = lua_isuserdata(L, 4) ? entity(L, 4) : NULL; + EntityType et = lua_isnumber(L, 5) ? (EntityType)lua_tointeger(L, 5) : ET_NOTYPE; + DamageType dt = lua_isnumber(L, 6) ? (DamageType)lua_tointeger(L, 6) : DT_NONE; + int lrStart = lua_isnumber(L, 7) ? lua_tointeger(L, 7) : -1; + int lrEnd = lua_isnumber(L, 8) ? lua_tointeger(L, 8) : -1; + + Entity *target = dsq->game->getNearestEntity(p, radius, ignore, ET_ENEMY, dt, lrStart, lrEnd); + luaReturnPtr(target); +} + luaFunc(findWall) { int x = lua_tonumber(L, 1); @@ -7062,21 +7255,21 @@ luaFunc(getMouseWorldPos) luaFunc(fade) { - dsq->overlay->color = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)); + dsq->overlay->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6)); dsq->overlay->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2)); luaReturnNil(); } luaFunc(fade2) { - dsq->overlay2->color = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)); + dsq->overlay2->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6)); dsq->overlay2->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2)); luaReturnNil(); } luaFunc(fade3) { - dsq->overlay3->color = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)); + dsq->overlay3->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6)); dsq->overlay3->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2)); luaReturnNil(); } @@ -7504,6 +7697,70 @@ luaFunc(text_setWidth) luaReturnNil(); } +luaFunc(loadShader) +{ + const char *vertRaw = getCString(L, 1); + const char *fragRaw = getCString(L, 2); + std::string vert, frag; + if(vertRaw) + findFile_helper(vertRaw, vert); + if(fragRaw) + findFile_helper(fragRaw, frag); + Shader *sh = new Shader(); + sh->load(vert, frag); + if(!sh->isLoaded()) + { + delete sh; + sh = NULL; + } + luaReturnPtr(sh); +} + +luaFunc(createShader) +{ + Shader *sh = new Shader(); + sh->loadSrc(getCString(L, 1), getCString(L, 2)); + if(!sh->isLoaded()) + { + delete sh; + sh = NULL; + } + luaReturnPtr(sh); +} + +luaFunc(shader_setAsAfterEffect) +{ + core->afterEffectManager->scriptShader = lua_isuserdata(L, 1) ? getShader(L, 1) : NULL; + luaReturnNil(); +} + +luaFunc(shader_setInt) +{ + Shader *sh = getShader(L, 1); + const char *name = getCString(L, 2); + if(sh && name) + sh->setInt(name, lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5), lua_tointeger(L, 6)); + luaReturnNil(); +} + +luaFunc(shader_setFloat) +{ + Shader *sh = getShader(L, 1); + const char *name = getCString(L, 2); + if(sh && name) + sh->setFloat(name, lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6)); + luaReturnNil(); +} + +luaFunc(shader_delete) +{ + Shader *sh = getShader(L); + delete sh; + if(core->afterEffectManager->scriptShader == sh) + core->afterEffectManager->scriptShader = NULL; + luaReturnNil(); +} + //-------------------------------------------------------------------------------------------- @@ -7541,11 +7798,15 @@ static const struct { luaRegister(getNoteName), luaRegister(getWorldType), + luaRegister(setWorldType), + luaRegister(setWorldPaused), + luaRegister(isWorldPaused), luaRegister(getWaterLevel), luaRegister(setWaterLevel), luaRegister(createQuad), + luaRegister(quad_setPauseLevel), luaRegister(setupEntity), luaRegister(setActivePet), @@ -7570,6 +7831,7 @@ static const struct { luaRegister(entity_setBoneLock), luaRegister(entity_setIngredient), luaRegister(entity_setDeathScene), + luaRegister(entity_isDeathScene), luaRegister(entity_setBeautyFlip), luaRegister(entity_setInvincible), @@ -7594,6 +7856,7 @@ static const struct { luaRegister(entity_setEatType), luaRegister(entity_setSpiritFreeze), + luaRegister(node_setSpiritFreeze), luaRegister(entity_setCanLeaveWater), @@ -7614,9 +7877,20 @@ static const struct { luaRegister(avatar_setCanDie), + luaRegister(setCanActivate), + luaRegister(setSeeMapMode), luaRegister(avatar_toggleCape), luaRegister(avatar_setPullTarget), + luaRegister(avatar_setCanLockToWall), + luaRegister(avatar_canLockToWall), + luaRegister(avatar_setCanBurst), + luaRegister(avatar_canBurst), + luaRegister(avatar_setCanSwimAgainstCurrents), + luaRegister(avatar_canSwimAgainstCurrents), + luaRegister(avatar_setCanCollideWithShots), + luaRegister(avatar_canCollideWithShots), + luaRegister(avatar_setCollisionAvoidanceData), luaRegister(avatar_clampPosition), luaRegister(avatar_updatePosition), @@ -7721,6 +7995,7 @@ static const struct { luaRegister(entity_getVectorToEntity), luaRegister(entity_getDistanceToTarget), + luaRegister(entity_getDistanceToPoint), luaRegister(entity_move), luaRegister(entity_getID), @@ -7818,6 +8093,7 @@ static const struct { luaRegister(entity_isTargetInRange), luaRegister(entity_getDistanceToEntity), + luaRegister(entity_isEntityInside), luaRegister(entity_isInvincible), @@ -7834,6 +8110,7 @@ static const struct { luaRegister(entity_setMaxSpeed), luaRegister(entity_getMaxSpeed), luaRegister(entity_setMaxSpeedLerp), + luaRegister(entity_getMaxSpeedLerp), luaRegister(entity_setState), luaRegister(entity_getState), luaRegister(entity_getEnqueuedState), @@ -8024,10 +8301,12 @@ static const struct { luaRegister(avatar_isRolling), luaRegister(avatar_isOnWall), luaRegister(avatar_isShieldActive), + luaRegister(avatar_setShieldActive), luaRegister(avatar_getRollDirection), luaRegister(avatar_fallOffWall), luaRegister(avatar_setBlockSinging), + luaRegister(avatar_isBlockSinging), luaRegister(avatar_toggleMovement), @@ -8223,7 +8502,7 @@ static const struct { luaRegister(setSceneColor), - + luaRegister(getSceneColor), luaRegister(entity_watchEntity), @@ -8251,6 +8530,7 @@ static const struct { luaRegister(entity_setTexture), luaRegister(entity_setFillGrid), + luaRegister(entity_isFillGrid), luaRegister(entity_push), @@ -8315,6 +8595,7 @@ static const struct { luaRegister(entity_getNearestEntity), luaRegister(entity_getNearestBoneToPosition), + luaRegister(getNearestEntity), luaRegister(entity_getNearestNode), luaRegister(entity_setPoison), @@ -8350,6 +8631,13 @@ static const struct { luaRegister(text_setFontSize), luaRegister(text_setWidth), + luaRegister(loadShader), + luaRegister(createShader), + luaRegister(shader_setAsAfterEffect), + luaRegister(shader_setFloat), + luaRegister(shader_setInt), + luaRegister(shader_delete), + luaRegister(isQuad), luaRegister(isNode), luaRegister(isObject), @@ -9033,6 +9321,7 @@ static const struct { luaConstant(DT_CRUSH), luaConstant(DT_SPIKES), luaConstant(DT_STEAM), + luaConstant(DT_WALLHURT), luaConstant(FRAME_TIME), @@ -9060,6 +9349,10 @@ static const struct { luaConstant(OT_INVISIBLEIN), luaConstant(OT_HURT), luaConstant(OT_INVISIBLEENT), + + luaConstant(SEE_MAP_NEVER), + luaConstant(SEE_MAP_DEFAULT), + luaConstant(SEE_MAP_ALWAYS), }; //============================================================================================ diff --git a/Aquaria/ScriptedEntity.cpp b/Aquaria/ScriptedEntity.cpp index 67aa2a1..10f4c9e 100644 --- a/Aquaria/ScriptedEntity.cpp +++ b/Aquaria/ScriptedEntity.cpp @@ -759,32 +759,6 @@ void ScriptedEntity::songNoteDone(int note, float len) } } -bool ScriptedEntity::isEntityInside() -{ - bool v = false; - int avatars = 0; - FOR_ENTITIES(i) - { - Entity *e = *i; - if (e->getEntityType() == ET_AVATAR) - avatars ++; - if (e && e->life == 1 && e != this && e->ridingOnEntity != this) - { - if (isCoordinateInside(e->position)) - { - /* - Vector diff = (e->position - position); - diff.setLength2D(100); - e->vel += diff; - */ - v = true; - } - } - - } - return v; -} - void ScriptedEntity::becomeSolid() { //vel = 0; diff --git a/Aquaria/ScriptedEntity.h b/Aquaria/ScriptedEntity.h index 3c13dc7..f943f6a 100644 --- a/Aquaria/ScriptedEntity.h +++ b/Aquaria/ScriptedEntity.h @@ -68,7 +68,6 @@ public: typedef std::vector Strands; Strands strands; int strandSpacing; - bool isEntityInside(); void becomeSolid(); std::string deathParticleEffect; diff --git a/Aquaria/Shot.cpp b/Aquaria/Shot.cpp index b52b762..757b041 100644 --- a/Aquaria/Shot.cpp +++ b/Aquaria/Shot.cpp @@ -342,6 +342,7 @@ Shot::Shot() : Quad(), Segmented(0,0) fired = false; target = 0; dead = false; + enqueuedForDelete = false; shotIdx = shots.size(); shots.push_back(this); } @@ -487,7 +488,6 @@ void Shot::setLifeTime(float l) void Shot::onEndOfLife() { destroySegments(0.2); - deleteShots.push_back(this); dead = true; if (emitter) @@ -495,6 +495,12 @@ void Shot::onEndOfLife() emitter->killParticleEffect(); emitter = 0; } + + if (!enqueuedForDelete) + { + enqueuedForDelete = true; + deleteShots.push_back(this); + } } void Shot::doHitEffects() @@ -778,7 +784,7 @@ bool Shot::isObstructed(float dt) const void Shot::onUpdate(float dt) { if (dsq->game->isPaused()) return; - if (dsq->continuity.getWorldType() != WT_NORMAL) return; + if (dsq->game->isWorldPaused()) return; if (!shotData) return; diff --git a/Aquaria/Shot.h b/Aquaria/Shot.h index 657a55c..3864dd2 100644 --- a/Aquaria/Shot.h +++ b/Aquaria/Shot.h @@ -128,7 +128,6 @@ public: protected: float waveTimer; - bool fired; void suicide(); @@ -141,6 +140,8 @@ protected: void onEndOfLife(); bool dead; + bool fired; + bool enqueuedForDelete; void onUpdate(float dt); private: diff --git a/Aquaria/SteamRender.cpp b/Aquaria/SteamRender.cpp index a6a5281..6502670 100644 --- a/Aquaria/SteamRender.cpp +++ b/Aquaria/SteamRender.cpp @@ -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 } diff --git a/Aquaria/Web.cpp b/Aquaria/Web.cpp index 262df92..1e25a31 100644 --- a/Aquaria/Web.cpp +++ b/Aquaria/Web.cpp @@ -150,7 +150,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); diff --git a/Aquaria/WorldMapRender.cpp b/Aquaria/WorldMapRender.cpp index e9f1b9f..add5195 100644 --- a/Aquaria/WorldMapRender.cpp +++ b/Aquaria/WorldMapRender.cpp @@ -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 { diff --git a/BBGE/AfterEffect.cpp b/BBGE/AfterEffect.cpp index 2879cf8..5e7a091 100644 --- a/BBGE/AfterEffect.cpp +++ b/BBGE/AfterEffect.cpp @@ -35,6 +35,7 @@ AfterEffectManager::AfterEffectManager(int xDivs, int yDivs) activeShader = AS_NONE; numEffects = 0; bRenderGridPoints = true; + scriptShader = 0; screenWidth = core->getWindowWidth(); screenHeight = core->getWindowHeight(); @@ -245,6 +246,7 @@ void AfterEffectManager::setActiveShader(ActiveShader as) activeShader = as; } + void AfterEffectManager::renderGrid() { #ifdef BBGE_BUILD_OPENGL @@ -278,11 +280,21 @@ void AfterEffectManager::renderGrid() activeShader = &glowShader; break; } + + if(scriptShader) + activeShader = scriptShader; + } if (activeShader) + { + //while(glGetError() != GL_NO_ERROR) {} + activeShader->bind(); + activeShader->setInt("tex", 0); + } + screenWidth = core->getWindowWidth(); screenHeight = core->getWindowHeight(); diff --git a/BBGE/AfterEffect.h b/BBGE/AfterEffect.h index fd755d3..bfe70f7 100644 --- a/BBGE/AfterEffect.h +++ b/BBGE/AfterEffect.h @@ -125,6 +125,7 @@ public: int textureWidth, textureHeight; Shader blurShader, bwShader, washoutShader, motionBlurShader, glowShader; + Shader *scriptShader; Vector ** drawGrid; diff --git a/BBGE/BBGECompileConfig.h b/BBGE/BBGECompileConfig.h index 762a1c6..125b5bf 100644 --- a/BBGE/BBGECompileConfig.h +++ b/BBGE/BBGECompileConfig.h @@ -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 diff --git a/BBGE/Base.cpp b/BBGE/Base.cpp index ebaa09c..6feee42 100644 --- a/BBGE/Base.cpp +++ b/BBGE/Base.cpp @@ -301,7 +301,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,7 +312,7 @@ void drawCircle(float radius, int stepSize) } glEnd(); - glEnable(GL_CULL_FACE); + //glEnable(GL_CULL_FACE); #endif } diff --git a/BBGE/BitmapFont.cpp b/BBGE/BitmapFont.cpp index dca022e..9bf0fc2 100644 --- a/BBGE/BitmapFont.cpp +++ b/BBGE/BitmapFont.cpp @@ -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 diff --git a/BBGE/Core.cpp b/BBGE/Core.cpp index b71581c..3bb0f1e 100644 --- a/BBGE/Core.cpp +++ b/BBGE/Core.cpp @@ -1840,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 @@ -3006,6 +3008,8 @@ void Core::main(float runTime) updateCullData(); + dbg_numRenderCalls = 0; + if (settings.renderOn) { if (verbose) debugLog("dark layer prerender"); diff --git a/BBGE/Core.h b/BBGE/Core.h index 84b08cb..8e45ab3 100644 --- a/BBGE/Core.h +++ b/BBGE/Core.h @@ -1310,6 +1310,7 @@ public: int zgaSave(const char *filename, short int width, short int height, unsigned char pixelDepth, unsigned char *imageData); volatile int dbg_numThreadDecoders; + static unsigned int dbg_numRenderCalls; protected: diff --git a/BBGE/Emitter.cpp b/BBGE/Emitter.cpp index d92a57a..31c693e 100644 --- a/BBGE/Emitter.cpp +++ b/BBGE/Emitter.cpp @@ -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); } diff --git a/BBGE/Quad.cpp b/BBGE/Quad.cpp index 5fa50ee..fdcfa38 100644 --- a/BBGE/Quad.cpp +++ b/BBGE/Quad.cpp @@ -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) diff --git a/BBGE/QuadTrail.cpp b/BBGE/QuadTrail.cpp index 3a2ecd8..a299b4e 100644 --- a/BBGE/QuadTrail.cpp +++ b/BBGE/QuadTrail.cpp @@ -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; diff --git a/BBGE/RenderObject.cpp b/BBGE/RenderObject.cpp index 032c4c8..69b5e6d 100644 --- a/BBGE/RenderObject.cpp +++ b/BBGE/RenderObject.cpp @@ -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 diff --git a/BBGE/RoundedRect.cpp b/BBGE/RoundedRect.cpp index 1657159..4eb86dc 100644 --- a/BBGE/RoundedRect.cpp +++ b/BBGE/RoundedRect.cpp @@ -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() diff --git a/BBGE/ScriptObject.cpp b/BBGE/ScriptObject.cpp index 452edbe..60b5d01 100644 --- a/BBGE/ScriptObject.cpp +++ b/BBGE/ScriptObject.cpp @@ -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 }; diff --git a/BBGE/ScriptObject.h b/BBGE/ScriptObject.h index 08cd693..a6bbb0a 100644 --- a/BBGE/ScriptObject.h +++ b/BBGE/ScriptObject.h @@ -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 }; diff --git a/BBGE/Shader.cpp b/BBGE/Shader.cpp index 90c7c5e..d29707e 100644 --- a/BBGE/Shader.cpp +++ b/BBGE/Shader.cpp @@ -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 -#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,36 @@ end: Shader::Shader() { - loaded = false; - mode = 0; + addType(SCO_SHADER); + 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 +173,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 +183,266 @@ 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); + + 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 +} diff --git a/BBGE/Shader.h b/BBGE/Shader.h index 1eb4cd9..3d21050 100644 --- a/BBGE/Shader.h +++ b/BBGE/Shader.h @@ -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 +class Shader : public ScriptObject { 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 UniformVec; + UniformVec uniforms; + + bool uniformsDirty; }; #endif diff --git a/ExternalLibs/algorithmx.h b/ExternalLibs/algorithmx.h new file mode 100644 index 0000000..44f85a0 --- /dev/null +++ b/ExternalLibs/algorithmx.h @@ -0,0 +1,34 @@ +#ifndef STDXfg_ALGORITHMX_H +#define STDXfg_ALGORITHMX_H + +// Some std:: namespace enhancements + +#include + +namespace stdx_fg { + +template +ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& val, Compare comp) +{ + ForwardIterator it; + typename std::iterator_traits::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 diff --git a/game_scripts/scripts/entities/cc_sunkencity.lua b/game_scripts/scripts/entities/cc_sunkencity.lua index 264bfc9..d793215 100644 --- a/game_scripts/scripts/entities/cc_sunkencity.lua +++ b/game_scripts/scripts/entities/cc_sunkencity.lua @@ -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 diff --git a/game_scripts/scripts/entities/energyboss.lua b/game_scripts/scripts/entities/energyboss.lua index 519babe..d2a6b2f 100644 --- a/game_scripts/scripts/entities/energyboss.lua +++ b/game_scripts/scripts/entities/energyboss.lua @@ -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") diff --git a/game_scripts/scripts/entities/predatorytunicate.lua b/game_scripts/scripts/entities/predatorytunicate.lua index 1960c0b..b6f6871 100644 --- a/game_scripts/scripts/entities/predatorytunicate.lua +++ b/game_scripts/scripts/entities/predatorytunicate.lua @@ -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 diff --git a/win/vc90/BBGE.vcproj b/win/vc90/BBGE.vcproj index b6cf501..ef5d40e 100644 --- a/win/vc90/BBGE.vcproj +++ b/win/vc90/BBGE.vcproj @@ -352,10 +352,6 @@ RelativePath="..\..\BBGE\ParticleManager.cpp" > - - diff --git a/win/vc90/external.vcproj b/win/vc90/external.vcproj index 0eb936d..ef30d30 100644 --- a/win/vc90/external.vcproj +++ b/win/vc90/external.vcproj @@ -1219,6 +1219,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + +