diff --git a/Aquaria/AnimationEditor.cpp b/Aquaria/AnimationEditor.cpp index 0b15386..105c094 100644 --- a/Aquaria/AnimationEditor.cpp +++ b/Aquaria/AnimationEditor.cpp @@ -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; + } + } + } + } + } } } } diff --git a/Aquaria/AquariaCompileConfig.h b/Aquaria/AquariaCompileConfig.h index 194b230..a7b9cd6 100644 --- a/Aquaria/AquariaCompileConfig.h +++ b/Aquaria/AquariaCompileConfig.h @@ -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 diff --git a/Aquaria/AquariaMenuItem.cpp b/Aquaria/AquariaMenuItem.cpp index 71d8689..c288058 100644 --- a/Aquaria/AquariaMenuItem.cpp +++ b/Aquaria/AquariaMenuItem.cpp @@ -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) diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index c2d43f5..941a4bc 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -117,8 +117,14 @@ const float NOTE_ACCEPT_DISTANCE = 25; // we accept a note. const float NOTE_ACCEPT_ANGLE_OFFSET = 15; -volatile int micNote = -1; -bool openedFromMicInput = false; +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; @@ -152,7 +158,7 @@ void Avatar::bindInput() dsq->user.control.actionSet.importAction(this, "PrimaryAction", ACTION_PRIMARY); dsq->user.control.actionSet.importAction(this, "SecondaryAction", ACTION_SECONDARY); - dsq->user.control.actionSet.importAction(this, "Revert", MakeFunctionEvent(Avatar, revert), 0); + dsq->user.control.actionSet.importAction(this, "Revert", ACTION_REVERT); dsq->user.control.actionSet.importAction(this, "SwimUp", ACTION_SWIMUP); dsq->user.control.actionSet.importAction(this, "SwimDown", ACTION_SWIMDOWN); @@ -462,7 +468,7 @@ void SongIcon::onUpdate(float dt) } if (alpha.x == 1) { - if ((!openedFromMicInput && isCoordinateInRadius(core->mouse.position, NOTE_ACCEPT_DISTANCE)) || micNote == note) + if (isCoordinateInRadius(core->mouse.position, NOTE_ACCEPT_DISTANCE)) { //if (delay == 0) if (true) @@ -487,7 +493,7 @@ void SongIcon::onUpdate(float dt) } } } - else if (openedFromMicInput || !isCoordinateInRadius(core->mouse.position, NOTE_ACCEPT_DISTANCE*1.25f)) + else if (!isCoordinateInRadius(core->mouse.position, NOTE_ACCEPT_DISTANCE*1.25f)) { if (cursorIsIn) { @@ -727,7 +733,6 @@ AvatarState::AvatarState() wasUnderWater = true; blind = false; lockedToWall = false; - crawlingOnWall = false; shotDelay = 0; spellCharge = 0; leachTimer = 0; @@ -738,14 +743,6 @@ AvatarState::AvatarState() blinkTimer = 0; } -// 0 1 2 3 4 5 6 7 8 9 -const int spellManaCost [] = { 0, 3, 1, 1, 2, 1, 4, 1, 1, 2}; -const float spellChargeMins [] = { 0, 1.25, 0, 0, 0.75, 0, 0.5, 0, 0, 3}; -//const float spellChargeMaxs [] = { 0.75, 1.5, 1.9, 1, 1, 1, 0.75, 1, 1, 3}; -const float spellCastDelays [] = { 0.05, 0.2, 0.4, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.1 }; - -bool avatarDebugEnabled = false; - void Avatar::toggleMovement(bool on) { canMove = on; @@ -753,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() @@ -761,11 +758,6 @@ bool Avatar::isSinging() return singing; } -void Avatar::shift() -{ - dsq->continuity.shiftWorlds(); -} - void Avatar::applyWorldEffects(WorldType type) { static bool oldfh=false; @@ -946,30 +938,6 @@ void Avatar::updatePosition() updateHair(0); } -void Avatar::debugMsg(const std::string &msg) -{ - if (avatarDebugEnabled) - { - BitmapText *txt = new BitmapText(&dsq->font); - txt->setLife(2); - txt->setDecayRate(1); - txt->position = this->position; - txt->setText(msg); - txt->fadeAlphaWithLife = true; - core->getTopStateData()->addRenderObject(txt, LR_DEBUG_TEXT); - } -} - -void Avatar::onBlindTest() -{ - setBlind(5); -} - -void Avatar::onToggleDebugMessages() -{ - avatarDebugEnabled = !avatarDebugEnabled; -} - void Avatar::updateHair(float dt) { static float hairTimer = 0; @@ -1451,170 +1419,9 @@ void Avatar::clearTargets() } } -void Avatar::slowToRest() -{ - vel.capLength2D(50); - /* - if (vel.getSquaredLength2D() > sqr(50)) - { - vel.setLength2D(50); - } - */ - bursting = swimming = false; - skeletalSprite.stopAnimation(1); - rotation.interpolateTo(Vector(0,0,0), 0.2, 0, 0, 1); -} - -/* -#define SPECWIDTH 368 -#define SPECHEIGHT 127 -BYTE *specbuf = 0; -*/ - -volatile int curMicNote = -1, lastMicNote=-1; - -#ifdef BBGE_BUILD_RECORD - volatile float timeFromLastNote=0; - volatile float timerFreq; - volatile float lastLargest=0; - volatile bool inMe = false; - volatile __int64 lastTick = 0; -#endif - - /* -BOOL CALLBACK recordCallback(HRECORD handle, const void *buf, DWORD len, DWORD user) -{ - -#ifdef BBGE_BUILD_RECORD - if (inMe) return TRUE; - inMe = true; - - //if (!dsq->game->avatar->isSinging()) return FALSE; - //int x,y; - - //timerFreq = - __int64 freq=0; - QueryPerformanceFrequency((LARGE_INTEGER*)&freq); - __int64 curTime=0; - QueryPerformanceCounter((LARGE_INTEGER*)&curTime); - if (lastTick == 0) - { - lastTick = curTime; - } - - float fft[4096]; // get the FFT data - BASS_ChannelGetData(handle,fft,BASS_DATA_FFT4096); - - int v = 0; - int c = 0; - float largest = -1; - - //128 - //for (int i = 5; i < 13; i++) - for (int i = 12; i < 64; i++) - { - if (fft[i] > 0.01f && (fft[i] > largest || largest == -1)) - { - largest = fft[i]; - v = i; - } - } - - int v2=0; - largest = -1; - // find the next largest - - float dt = (float(curTime-lastTick)/float(freq)); - lastTick = curTime; - int posMicNote=-1; - if (c != 0) - v /= float(c); - int ov = v; - float factor=1.0; - int octave = dsq->user.audio.octave; - - int minNote = 12;///6; - int maxNote = minNote + 25; // 8 - int octRange = 11; - - minNote += (octRange)*octave; - maxNote += (octRange)*octave; - - posMicNote = dsq->fftnotes.getNoteFromFFT(v, octave); - - //if (lastLargest 0.0001f) - { - micNote = curMicNote; - timeFromLastNote = 0; - } - if (curMicNote == -1) - micNote = -1; - lastMicNote = curMicNote; - - inMe = false; -#endif - return TRUE; -} -*/ - -/* - -class FoodIcon2 : public Quad -{ -}; - -class FoodIcon : public Quad -{ -public: - FoodIcon(IngredientEffectType iet); - - IngredientEffectType type; - - void -}; - -void Avatar::openFoodInterface() -{ - if (!singing && !pickingPullTarget && health > 0 && !isEntityDead() && !blockSinging) - { - // build it - foodIcons.clear(); - - foodIcons.resize(8); - } -} -*/ - void Avatar::openSingingInterface() { - if (!singing && !pickingPullTarget && health > 0 && !isEntityDead() && !blockSinging) + if (!singing && health > 0 && !isEntityDead() && !blockSinging) { //core->mouse.position = Vector(400,300); if (dsq->inputMode != INPUT_MOUSE) @@ -1635,19 +1442,10 @@ void Avatar::openSingingInterface() } currentSong.notes.clear(); - // songInterfaceTimer = 0; dsq->game->songLineRender->clear(); - //if (avatarRecord) - //{ - // if (dsq->useMic && !dsq->autoSingMenuOpen && dsq->user.audio.micOn) - // { - // //avatarRecord=BASS_RecordStart(44100,1,0,&recordCallback,0); - // BASS_ChannelPlay(avatarRecord, false); - // } - //} if (dsq->inputMode == INPUT_JOYSTICK) { @@ -1686,48 +1484,6 @@ void Avatar::closeSingingInterface() dsq->continuity.castSong(currentSongIdx); currentSongIdx = SONG_NONE; } - - /* - if (avatarRecord) - { - if (dsq->useMic && !dsq->autoSingMenuOpen && dsq->user.audio.micOn) - { - //BASS_ChannelStop(avatarRecord); - BASS_ChannelPause(avatarRecord); - //BASS_RecordFree(); - //avatarRecord = 0; - - } - } - */ - - lastMicNote = curMicNote = micNote = -1; - } -} - -void Avatar::openFormInterface() -{ - if (!inFormInterface) - { - inFormInterface = true; - - for(int i = 0; i < formIcons.size(); i++) - { - formIcons[i]->alpha.interpolateTo(1, 0.1); - } - } -} - -void Avatar::closeFormInterface() -{ - if (inFormInterface) - { - inFormInterface = false; - - for (int i = 0; i < formIcons.size(); i++) - { - formIcons[i]->alpha.interpolateTo(0, 0.1); - } } } @@ -1838,6 +1594,10 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF return; } //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: @@ -1849,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()) @@ -1861,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) { @@ -1874,7 +1641,6 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF state.abilityDelay = 0; formAbilityDelay = 0; dsq->continuity.form = form; - ropeState = 0; formTimer = 0; if (effects) { @@ -1969,6 +1735,10 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF refreshModel("FishForm", ""); //rotationOffset.interpolateTo(Vector(0,0,-90), 0.5); //refreshModel("NaijaFish", ""); + + collideRadius = COLLIDE_RADIUS_FISH; + setCanLockToWall(false); + setCollisionAvoidanceData(COLLIDE_RANGE_FISH, COLLIDE_MOD_FISH); } break; case FORM_SUN: @@ -2000,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: @@ -2043,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) { @@ -2092,33 +1837,10 @@ void Avatar::singNote(int note) { currentSong.notes.push_back(note); lastNote = note; - //int song = dsq->continuity.checkSong(currentSong); - //int song = dsq->continuity.checkSongAssisted(currentSong); - //int song = dsq->continuity.checkSongAssisted(currentSong); - /* - std::ostringstream os; - os << "sung note: " << note; - debugLog(os.str()); - */ - //currentSongIdx = song; - /* - if (song != -1) - { - */ - /* - std::ostringstream os; - os << "Sung Song: " << song; - debugLog(os.str()); - */ - // close in a few seconds - //closeSingingInterface(); - //} } void Avatar::updateSingingInterface(float dt) { - - //if (singing) if (songIcons.size()>0 && songIcons[0]->alpha.x > 0) { if (dsq->inputMode != INPUT_JOYSTICK && !core->mouse.change.isZero()) @@ -2436,7 +2158,8 @@ void Avatar::loseTargets() void Avatar::updateTargetQuads(float dt) { - particleManager->setSuckPosition(1, dsq->getGameCursorPosition()); + const Vector cursorpos = dsq->getGameCursorPosition(); + particleManager->setSuckPosition(1, cursorpos); /* for (int i = 0; i < targetQuads.size(); i++) @@ -2467,7 +2190,8 @@ void Avatar::updateTargetQuads(float dt) targets[i].pos = e->getTargetPoint(targets[i].targetPt); if (i == 0) { - particleManager->setSuckPosition(1, targets[i].pos); + particleManager->setSuckPosition(1, targets[i].pos); // suckpos 1 is overridden elsewhere later + particleManager->setSuckPosition(2, targets[i].pos); } /* @@ -2480,7 +2204,7 @@ void Avatar::updateTargetQuads(float dt) } else { - targetQuads[i]->position = dsq->getGameCursorPosition(); + targetQuads[i]->position = cursorpos; //targetQuads[i]->alpha.interpolateTo(0, 0.1); } } @@ -2500,7 +2224,7 @@ void Avatar::updateTargetQuads(float dt) debugLog(os.str()); */ - targetQuads[i]->position = dsq->getGameCursorPosition(); + targetQuads[i]->position = cursorpos; if (dsq->continuity.form == FORM_ENERGY && isInputEnabled()) { if (dsq->inputMode == INPUT_JOYSTICK && targetQuads[i]->isRunning()) @@ -2703,22 +2427,6 @@ bool Avatar::fireAtNearestValidEntity(const std::string &shot) return firedShot; } -void Avatar::spawnSeed() -{ - // max spore children/seeds = 50 - if (dsq->game->getNumberOfEntitiesNamed("SporeChild") < 4) - { - if (!dsq->game->isObstructed(TileVector(position))) - { - dsq->game->createEntity("SporeChild", 0, position, 0, 0, ""); - } - } - else - { - // visual effect and/or sound effect - } -} - Vector Avatar::getFacing() { if (vel.isLength2DIn(2) && rotation.z == 0) @@ -2902,12 +2610,6 @@ void Avatar::formAbility(int ability) { if (chargeLevelAttained == 2) { - /* - shockTimer = 1; - damageDelay = 0.2; - didShockDamage = false; - */ - didShockDamage = false; if (dsq->continuity.hasFormUpgrade(FORMUPGRADE_ENERGY2)) doShock("EnergyTendril2"); else @@ -3199,7 +2901,7 @@ void Avatar::formAbility(int ability) for (i = Shot::shots.begin(); i != Shot::shots.end(); i++) { Shot *s = (*i); - if (s->shotData && !s->shotData->invisible) + if (s->isActive() && s->shotData && !s->shotData->invisible) { if (!s->firer || s->firer->getEntityType()==ET_ENEMY) { @@ -3438,70 +3140,6 @@ void Avatar::doShock(const std::string &shotName) { targets.clear(); } - - - /* - // old method - for (int i = 0; i < entitiesToHit.size(); i++) - { - Entity *e = entitiesToHit[i]; - DamageData d; - d.attacker = this; - d.damageType = DT_AVATAR_SHOCK; - d.damage = 3; - e->damage(d); - - dsq->playVisualEffect(VFX_SHOCKHIT, e->position, e); - - EnergyTendril *t = new EnergyTendril(this, e); - core->addRenderObject(t, LR_PARTICLES); - - e->shock(); - } - */ - - //HACK: WHAT DOES THIS VARIABLE DO EXACTLY? - didShockDamage = true; - - - //loseTargets(); -} - -void Avatar::updateShock(float dt) -{ - /* - if (shockTimer > 0) - { - float shockTime = 0.75; - castShockTimer += dt; - std::vector closestEntities; - unsigned int c=0; - const float shotDelayTime = 0.05; - - - if (damageDelay > 0) - { - damageDelay -= dt; - if (damageDelay <= 0) - damageDelay = 0; - } - - if (damageDelay == 0) - { - } - - if (damageDelay == 0) - { - damageDelay = 999; - } - - shockTimer -= dt; - if (shockTimer < 0) - { - shockTimer = 0; - } - } - */ } void Avatar::formAbilityUpdate(float dt) @@ -3534,58 +3172,6 @@ void Avatar::formAbilityUpdate(float dt) break; case FORM_ENERGY: { - /* - if (core->mouse.buttons.right && mana > 0 && !core->mouse.buttons.left) - { - float shockTime = 0.75; - castShockTimer += dt; - std::vector closestEntities; - unsigned int c=0; - const float shotDelayTime = 0.05; - - - int maxHit = 2 + dsq->continuity.getSpellLevel(SPELL_SHOCK)*2; - FOR_ENTITIES (i) - { - Entity *e = *i; - Vector d = e->position - this->position; - if (e != this && !e->isEntityDead() && e->isAffectedBySpell(SPELL_SHOCK) && d.getSquaredLength2D() < sqr(400+(dsq->continuity.getSpellLevel(SPELL_SHOCK)-1)*100)) - { - state.shotDelay += dt; - if (state.shotDelay > shotDelayTime) - { - state.shotDelay -= shotDelayTime; - - EnergyTendril *t = new EnergyTendril(avatar->position, e->position); - core->addRenderObject(t, LR_PARTICLES); - } - e->offset.x = rand()%5; - e->shock(); - DamageData d; - d.attacker = this; - d.spellType = SPELL_SHOCK; - d.damage = 1+(dsq->continuity.getSpellLevel(SPELL_SHOCK)-1)*1; - e->hit(d); - c ++; - } - if (c >= maxHit) - break; - } - //std::ostringstream os; - //os << "castShockTimer: " << castShockTimer << " - shockTime: " << shockTime; - //debugLog(os.str()); - if (castShockTimer > shockTime) - { - castShockTimer -= shockTime; - mana --; - } - } - else - { - state.shotDelay = 0; - endShock(); - } - */ } break; } @@ -3600,14 +3186,6 @@ bool Avatar::isMouseInputEnabled() return true; } -int rmb_flag = 0; -void Avatar::rmbd2() -{ - rmb_flag = 1; - rmbd(); - rmb_flag = 0; -} - void Avatar::rmbd() { //core->setDockIcon("BitBlot"); @@ -3616,7 +3194,7 @@ void Avatar::rmbd() { //if (isCoordinateInRadius(dsq->getGameCursorPosition(), 96)) ///Vector diff = core->mouse.position - c; - if (dsq->inputMode == INPUT_MOUSE && !rmb_flag) + if (dsq->inputMode == INPUT_MOUSE) { Vector diff = getVectorToCursorFromScreenCentre(); if (diff.getSquaredLength2D() < sqr(openSingingInterfaceRadius)) @@ -3629,13 +3207,8 @@ void Avatar::rmbd() } else { - if (spellCastDelay == 0) - startCharge(0); + startCharge(0); } - /* - if (spellCastDelay == 0) - startCharging(1); - */ } void Avatar::rmbu() @@ -3654,17 +3227,6 @@ void Avatar::rmbu() dsq->cursorGlow->alpha.interpolateTo(0, 0.2); dsq->cursorBlinker->alpha.interpolateTo(0, 0.2); - if (pickingPullTarget) - { - if (potentialPullTarget) - { - pullTarget = potentialPullTarget; - debugLog("Calling start pull"); - pullTarget->startPull(); - } - closePullTargetInterface(); - } - if (singing) { closeSingingInterface(); @@ -3681,16 +3243,6 @@ void Avatar::rmbu() pathToActivate->activate(); pathToActivate = 0; } - - - - /* - if (charging) - { - formAbility(1); - endCharge(); - } - */ } bool Avatar::canCharge(int ability) @@ -3701,22 +3253,9 @@ bool Avatar::canCharge(int ability) if (ability == 0) return true; break; case FORM_BEAST: - //if (inTummy) return true; + return false; break; case FORM_DUAL: - /* - if (dualFormMode == DUALFORM_NAIJA) - { - if (dualFormCharge >= requiredDualFormCharge) - { - return true; - } - } - else - { - return true; - } - */ return true; break; case FORM_NATURE: @@ -3746,17 +3285,8 @@ void Avatar::startCharge(int ability) dsq->loops.charge = core->sound->playSfx(sfx); state.spellCharge = 0; - spellChargeMin = 0; chargeLevelAttained = 0; - /* - chargeGraphic->alpha = 0; - chargeGraphic->scale = Vector(0,0); - chargeGraphic->alpha.interpolateTo(0.6, chargeMax, 0); - float sz = 1.5; - chargeGraphic->scale.interpolateTo(Vector(sz,sz), chargeMax, 0); - */ - switch(dsq->continuity.form) { case FORM_ENERGY: @@ -3779,7 +3309,6 @@ void Avatar::startCharge(int ability) chargingEmitter->start(); charging = true; - abilityCharging = ability; } if (!canCharge(ability)) @@ -3795,11 +3324,6 @@ void Avatar::setBlockSinging(bool v) bool Avatar::canSetBoneLock() { - /* - if (dsq->continuity.form == FORM_FISH || dsq->continuity.form == FORM_SPIRIT) - return false; - */ - return true; } @@ -3849,13 +3373,6 @@ void Avatar::lmbd() } } } - /* - else - { - if (spellCastDelay == 0) - startCharging(0); - } - */ } void Avatar::fallOffWall() @@ -3910,17 +3427,6 @@ void Avatar::endCharge() dsq->loops.charge = BBGE_AUDIO_NOCHANNEL; } - - /* - std::ostringstream os; - os << "spellCharge: " << spellCharge; - debugLog(os.str()); - */ - /* - chargeGraphic->alpha.interpolateTo(0, 0.5, 0); - chargeGraphic->scale.interpolateTo(Vector(0,0), 1.0, 0); - */ - chargingEmitter->stop(); charging = false; @@ -3931,37 +3437,6 @@ void Avatar::endCharge() Vector Avatar::getWallNormal(TileVector t) { return dsq->game->getWallNormal(t.worldVector(), 5)*-1; - - /* - Vector accum; - int c = 0; - for (int x = -2; x <= 2; x++) - { - for (int y = -2; y <= 2; y++) - { - TileVector check = t; - check.x+=x; - check.y+=y; - if (!dsq->game->isObstructed(check)) - { - Vector v(check.x, check.y); - c++; - accum+= v; - } - //check.x+x, check.y+y - } - } - if (c > 0) - { - accum /= c; - //accum.normalize2D(); - accum.setLength2D(-1); - return accum; - } - Vector v = vel; - v.setLength2D(-1); - return v; - */ } int Avatar::getSingingInterfaceRadius() @@ -3993,7 +3468,6 @@ void Avatar::lockToWallCommon() stopRoll(); core->sound->playSfx("LockToWall", 1.0, 0);//, (1000+rand()%100)/1000.0f); //bursting = false; - animatedBurst = false; this->burst = 1; //lastLockToWallPos = position; @@ -4010,17 +3484,12 @@ 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; - /* - Vector opos = position; - position = lastPosition; - */ - TileVector t(position); TileVector myTile = t; // 3 + 4 @@ -4029,12 +3498,7 @@ void Avatar::lockToWall() m.setLength2D(3); t.x += int(m.x); t.y += int(m.y); - /* - TileVector t2 = t; - m.setLength2D(4); - t2.x += int(m.x); - t2.y += int(m.y); - */ + m.setLength2D(2); TileVector tback = myTile; tback.x += int(m.x); @@ -4046,27 +3510,6 @@ void Avatar::lockToWall() tnext.x += int(add.x); tnext.y += int(add.y); - // find the fraking wall - /* - TileVector actualWall = myTile; - Vector lastWall; - Vector getWall(myTile.x, myTile.y); - for (int i = -1; i < 5; i++) - { - getWall.x += add.x*i; - getWall.y += add.y*i; - if (lastWall.isZero()) - lastWall = getWall; - TileVector test(getWall.x, getWall.y); - if (dsq->game->isObstructed(test)) - break; - lastWall = getWall; - } - actualWall = TileVector(lastWall.x, lastWall.y); - */ - - Vector diff = lastLockToWallPos - position; - bool good = true; if (!dsq->game->isObstructed(t)) { @@ -4140,7 +3583,7 @@ void Avatar::lockToWall() } } - if (dsq->game->getGrid(t)==OT_HURT && dsq->continuity.form != FORM_NATURE) + if (dsq->game->getGrid(t)==OT_HURT && isDamageTarget(DT_WALLHURT)) { good = false; } @@ -4168,12 +3611,6 @@ void Avatar::lockToWall() } else { - - /* - position = TileVector(position).worldVector(); - lastPosition = position; - */ - if (!dsq->mod.isActive() && !dsq->continuity.getFlag("lockedToWall")) { @@ -4190,9 +3627,6 @@ void Avatar::lockToWall() else lockToWallFallTimer = -1; - //wallPushVec = getWallNormal(t); - - wallPushVec = wallNormal; wallPushVec *= 2000; wallPushVec.z = 0; @@ -4248,47 +3682,12 @@ void Avatar::lockToWall() { time = len/spd; } - /* - std::ostringstream os; - os << "time: " << time; - debugLog(os.str()); - */ offset.interpolateTo(offdiff, time); - /* - if (tileType == OT_INVISIBLEIN) - { - goIn = wallNormal; - goIn.setLength2D(-28); - } - else - { - Vector diff = uset.worldVector()-position; - goIn = diff; - } - offset.interpolateTo(goIn, 0.05); - */ wallLockTile = t; vel = Vector(0,0,0); vel2 = 0; - - /* - Vector oldPos = position; - - while (true) - { - Vector m = vel; - m |= 1; - position += m; - TileVector t(position); - if (dsq->game->isObstructed(t, OT_BLACK)) - { - position = oldPos; - break; - } - } - */ } } else @@ -4405,28 +3804,6 @@ void Avatar::setNearestPullTarget() } } -void Avatar::openPullTargetInterface() -{ - debugLog("Open pull target"); - if (pullTarget) - { - pullTarget->stopPull(); - } - pullTarget = 0; - potentialPullTarget = 0; - pickingPullTarget = true; - // change the cursor - dsq->cursor->color = Vector(0.5,0.5,1); -} - -void Avatar::closePullTargetInterface() -{ - debugLog("close pull target"); - pickingPullTarget = false; - potentialPullTarget = 0; - dsq->cursor->color = Vector(1,1,1); -} - void Avatar::createWeb() { web = new Web; @@ -4455,7 +3832,6 @@ Avatar::Avatar() : Entity(), ActionMapper() urchinDelay = 0; jellyDelay = 0; - warpIn = false; #ifdef AQ_TEST_QUADTRAIL quadTrail = new QuadTrail(100, 32); quadTrail->setTexture("Particles/QuadTrail"); @@ -4485,7 +3861,6 @@ Avatar::Avatar() : Entity(), ActionMapper() //registerEntityDied = true; setv(EV_ENTITYDIED, 1); - wallJumps = 0; wallBurstTimer = 0; beautyFlip = false; invincibleBreak = true; @@ -4494,7 +3869,6 @@ Avatar::Avatar() : Entity(), ActionMapper() songInterfaceTimer = 0; quickSongCastDelay = 0; flourish = false; - tummyAmount=0; blockSinging = false; singing = false; @@ -4519,31 +3893,17 @@ Avatar::Avatar() : Entity(), ActionMapper() fallGravityTimer = 0; lastOutOfWaterMaxSpeed = 0; //chargeGraphic = 0; - tummyTimer = 0; - inTummy = EAT_NONE; - ropeTimer = shieldPoints = auraTimer = 0; + shieldPoints = auraTimer = 0; glow = 0; fireDelay = 0; - inFormInterface = false; looking = false; - canWarpDelay = 0.5; - canWarp = false; rollDidOne = 0; lastQuad = lastQuadDir = rollDelay = rolling = 0; - stopTimer = 0; - doubleClickDelay = 0; - damageDelay = 0; - didShockDamage = false; chargeLevelAttained = 0; - shockTimer = 0; activeAura = AURA_NONE; - ropeState = 0; movingOn = false; currentMaxSpeed = 0; - abilityCharging = -1; - pickingPullTarget = false; - potentialPullTarget = 0; pullTarget = 0; revertTimer = 0; currentSongIdx = -1; @@ -4556,7 +3916,6 @@ Avatar::Avatar() : Entity(), ActionMapper() activateEntity = 0; canMove = true; - castShockTimer = 0; //scale = Vector(0.5, 0.5); scale = Vector(0.5, 0.5); @@ -4569,9 +3928,6 @@ Avatar::Avatar() : Entity(), ActionMapper() targets.resize(1); - - lastEntityActivation = 0; - entityToActivate = 0; pathToActivate = 0; zoomOverriden = false; @@ -4580,23 +3936,17 @@ Avatar::Avatar() : Entity(), ActionMapper() zoomVel = 0; myZoom = Vector(1,1); - spellChargeMin = spellCastDelay = 0; this->pushingOffWallEffect = 0; lockToWallFallTimer = 0; swimming = false; - dodgeDelay = 0; charging = false; bursting = false; - animatedBurst = false; burst = 1; burstDelay = 0; ignoreInputDelay = 0; - idleAnimDelay = 2; splashDelay = 0; avatar = this; - frame = 0; - particleDelay = 0; swimming = false; @@ -4657,27 +4007,6 @@ Avatar::Avatar() : Entity(), ActionMapper() fader->alpha = 0; dsq->game->addRenderObject(fader, LR_AFTER_EFFECTS); - text = 0; - - /* - chargeGraphic = new Particle; - { - chargeGraphic->setBlendType(RenderObject::BLEND_ADD); - chargeGraphic->setTexture("glow"); - chargeGraphic->alpha = 0; - //chargeGraphic->color = Vector(1,,0); - chargeGraphic->width = 128; - chargeGraphic->height = 128; - chargeGraphic->scale = Vector(0,0); - chargeGraphic->parentManagedPointer = 1; - //chargeGraphic->positionSnapTo = &this->position; - chargeGraphic->rotation.interpolateTo(Vector(0,0,360), 1, -1, 1); - chargeGraphic->position = Vector(16, 58); - //chargeGraphic->color = Vector(1,0.2,0.1); - } - //skeletalSprite.getBoneByIdx(3)->addChild(chargeGraphic); - */ - debugLog("Avatar 6"); targetQuads.resize(targets.size()); @@ -4731,10 +4060,6 @@ Avatar::Avatar() : Entity(), ActionMapper() chargingEmitter = new ParticleEffect; dsq->getTopStateData()->addRenderObject(chargingEmitter, LR_PARTICLES); - /* - addChild(&chargingEmitter); - chargingEmitter.parentManagedStatic = true; - */ chargeEmitter = new ParticleEffect; dsq->getTopStateData()->addRenderObject(chargeEmitter, LR_PARTICLES_TOP); @@ -4745,19 +4070,6 @@ Avatar::Avatar() : Entity(), ActionMapper() rightHandEmitter = new ParticleEffect; dsq->getTopStateData()->addRenderObject(rightHandEmitter, LR_PARTICLES); - /* - leftHandEmitter = new ParticleEffect; - dsq->getTopStateData()->addRenderObject(`, LR_PARTICLES); - - rightHandEmitter = new ParticlesEffect; - dsq->getTopStateData()->addRenderObject(rightHandEmitter, LR_PARTICLES); - */ - - /* - addChild(&chargeEmitter); - chargeEmitter.parentManagedStatic = true; - */ - addChild(&biteLeftEmitter, PM_STATIC); biteLeftEmitter.load("BiteLeft"); @@ -4795,36 +4107,28 @@ Avatar::Avatar() : Entity(), ActionMapper() debugLog("Avatar 9"); - if (dsq->useMic) - { - debugLog("useMic...initing recording"); - - /* - debugLog("RecordStart..."); - avatarRecord = BASS_RecordStart(44100,1,0,&recordCallback,0); - - if (avatarRecord) - { - if (dsq->autoSingMenuOpen) - { - } - else - { - debugLog("ChannelPause..."); - BASS_ChannelPause(avatarRecord); - } - } - debugLog("...done"); - */ - } - - debugLog("Avatar 10"); setDamageTarget(DT_AVATAR_LANCE, false); //changeForm(FORM_NORMAL, false); refreshNormalForm(); + if(dsq->continuity.form == FORM_FISH) + 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() @@ -4946,8 +4250,6 @@ void Avatar::destroy() { Entity::destroy(); - text = 0; - if (dsq->loops.shield != BBGE_AUDIO_NOCHANNEL) { core->sound->fadeSfx(dsq->loops.shield, SFT_OUT, 1); @@ -4962,24 +4264,6 @@ void Avatar::destroy() avatar = 0; } -void Avatar::fireRope() -{ - ropeVel = getAim(); - ropeVel.z = 0; - if (!ropeVel.isLength2DIn(1)) - { - ropeTimer = 0.2; - ropeState = 1; - ropePos = position; - //ropeVel = core->mouse.position - Vector(400,300); - - ropeVel.setLength2D(7000); - //ropeVel |= 500; - } - else - ropeVel = Vector(0,0,0); -} - void Avatar::toggleZoom() { if (core->globalScale.isInterpolating()) return; @@ -4992,56 +4276,6 @@ void Avatar::toggleZoom() else if (core->globalScale.x == 0.25) core->globalScale.interpolateTo(Vector(1,1),0.2); - /* - else if (core->globalScale.x == 1.5) - core->globalScale.interpolateTo(Vector(1,1),0.2); - */ - -} - -/* -void Avatar::setActiveSpell(Spells spell) -{ - activeSpell = spell; -} -*/ - -void Avatar::dodge(std::string dir) -{ - if (bursting) return; - if (!canMove) return; - if (dodgeDelay == 0) - { - Vector mov; - - if (dir == "right") - mov = Vector(1,0); - else if (dir == "left") - mov = Vector(-1, 0); - else if (dir == "down") - mov = Vector(0, 1); - else if (dir == "up") - mov = Vector(0, -1); - - Vector lastPosition = position; - //position += mov * 80; - - dodgeVec = mov * 8000; - vel += mov * vars->maxDodgeSpeed; - //dodgeEffectTimer = 0.125; - state.dodgeEffectTimer.start(/*0.125*/vars->dodgeTime); - /* - float vlen = vel.getLength2D(); - mov |= 500; - vel += mov; - */ - /* - if (dsq->game->collideCircleWithGrid(position, 24)) - { - position = lastPosition; - } - */ - } } void Avatar::startBackFlip() @@ -5091,25 +4325,7 @@ void Avatar::startBurstCommon() void Avatar::startBurst() { - //getVectorToCursorFromScreenCentre() - //!bursting && burst == 1 - //&& - /* - bool nearWallProblem = false; - if (vel.isLength2DIn(200)) - { - if () - { - nearWallProblem = false - } - else - { - nearWallProblem = true; - } - } - */ - //&& !vel.isLength2DIn(32) - 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)) { @@ -5187,35 +4403,6 @@ void Avatar::startWallBurst(bool useCursor) if (goDir.x != 0 || goDir.y != 0) { lastBurstType = BURST_WALL; - /* - if (wallBurstTimer > 0) - { - Vector wallJumpDir = position - lastWallJumpPos; - if (lastWallJumpPos.isZero() || wallJumpDir.dot2D(lastWallJumpPos) > 0.2f) - { - std::ostringstream os; - os << "wallJumps: " << wallJumps; - debugLog(os.str()); - wallJumps++; - } - else - { - debugLog("failed angle"); - stopWallJump(); - } - } - wallBurstTimer = 0.8f - 0.1f * wallJumps; - if (wallBurstTimer <= 0) - { - // super boost! - debugLog("super boost!"); - wallJumps = 0; - } - - - lastWallJumpPos = position; - lastWallJumpDir = position - lastWallJumpPos; - */ dsq->rumble(0.22, 0.22, 0.2); bittenEntities.clear(); @@ -5242,10 +4429,6 @@ void Avatar::startWallBurst(bool useCursor) vel = wallPushVec; this->state.lockedToWall = false; skeletalSprite.stopAllAnimations(); - if (wallJumps > 0) - { - dsq->sound->playSfx("WallJump", 255, 0, 1000+wallJumps*100); - } dsq->game->playBurstSound(pushingOffWallEffect>0); skeletalSprite.animate(getBurstAnimName(), 0); bursting = true; @@ -5253,56 +4436,6 @@ void Avatar::startWallBurst(bool useCursor) ripples = true; startBurstCommon(); - /* - if (core->afterEffectManager) - core->afterEffectManager->addEffect(new ShockEffect(Vector(core->width/2, core->height/2),core->screenCenter,0.04,0.06,15,0.2f)); - */ - - - /* - float len = wallPushVec.getLength2D(); - goDir |= len; - goDir.z = 0; - - Vector test = goDir; - test |= TILE_SIZE*2; - if (dsq->game->isObstructed(TileVector(position + test))) - { - } - else - wallPushVec = goDir; - */ - /* - wallPushVec = Vector((wallPushVec.x+goDir.x)/2, (wallPushVec.y+goDir.y)/2); - wallPushVec |= len; - */ - } - else - { - //wallPushVec |= 10; - } - } -} - -void Avatar::doDodgeInput(const std::string &action, int s) -{ - if (s) - { - if (tapped.empty()) - { - tapped = action; - state.tapTimer.start(0.25); - } - else if (tapped == action) - { - if (state.tapTimer.isActive()) - dodge(action); - tapped = ""; - dodgeDelay = 1.0; - } - else - { - tapped = ""; } } } @@ -5350,18 +4483,6 @@ Vector Avatar::getFakeCursorPosition() Vector Avatar::getVectorToCursorFromScreenCentre() { - /* - if (core->joystickEnabled) - { - Vector joy(core->joystate.lX-(65536/2), core->joystate.lY-(65536/2)); - float len = (joy.getLength2D() * 600) / 65536; - joy.setLength2D(len); - std::ostringstream os; - os << "joy (" << joy.x << ", " << joy.y << ")"; - debugLog(os.str()); - return joy; - } - */ if (game->cameraOffBounds) return getVectorToCursor(); else @@ -5385,54 +4506,27 @@ Vector Avatar::getVectorToCursor(bool trueMouse) //return core->mouse.position - Vector(400,300); } -void Avatar::startWallCrawl() -{ - lastWallNormal = wallNormal; - state.crawlingOnWall = true; - skeletalSprite.transitionAnimate("crawl", 0.1, -1); -} - -void Avatar::stopWallCrawl() -{ - state.crawlingOnWall = false; - state.lockedToWall = false; - idle(); -} - void Avatar::action(int id, int state) { if (id == ACTION_PRIMARY) { if (state) lmbd(); else lmbu(); } if (id == ACTION_SECONDARY) { if (state) rmbd(); else rmbu(); } + if (id == ACTION_REVERT && !state) + revert(); + if (id == ACTION_PRIMARY && state)// !state { if (isMiniMapCursorOkay()) { - if (this->state.lockedToWall && !this->state.crawlingOnWall) + if (this->state.lockedToWall) { Vector test = getVectorToCursor(); if (test.isLength2DIn(minMouse)) { fallOffWall(); - // previously didn't fall off wall with mouse.... why? - /* - //fallOffWall(); - if (dsq->inputMode == INPUT_JOYSTICK || dsq->inputMode == INPUT_KEYBOARD) - fallOffWall(); - */ } - /* - else if (test.isLength2DIn(maxMouse)) - { - this->state.lockedToWall = false; - idle(); - } - */ else { - //if (dsq->continuity.setFlag("lockedToWall", 1) - - //!boneLock.entity && if (boneLock.entity) wallNormal = boneLock.wallNormal; @@ -5470,15 +4564,6 @@ void Avatar::action(int id, int state) } } - /* - else - { - wallNormal = getWallNormal(TileVector(position)); - Vector left = wallNormal.getPerpendicularLeft(); - Vector right = wallNormal.getPerpendicularRight(); - position += left*0.1f; - } - */ } else { @@ -5494,24 +4579,7 @@ void Avatar::action(int id, int state) } } } - /* - // song note keys - else if (!action.empty() && action[0] == 's') - { - if (isSinging()) - { - int count=0; - std::istringstream is(action.substr(1, action.size())); - is >> count; - count--; - if (count >= 0 && count <= 7) - { - core->setMousePosition(songIcons[count]->position); - } - } - } - */ else if (id >= ACTION_SONGSLOT1 && id < ACTION_SONGSLOTEND) { if (canQuickSong()) @@ -5619,238 +4687,33 @@ void Avatar::action(int id, int state) } } -void Avatar::doRangePull(float dt) +void Avatar::doBindSong() { - int range = 4; - Vector total; - - Vector dest = position + vel*dt; - TileVector t(dest); - std::vector vectors; - for (int x = t.x-range; x <= t.x+range; x++) + if (pullTarget) { - for (int y = t.y-range; y <= t.y+range; y++) + pullTarget->stopPull(); + pullTarget = 0; + core->sound->playSfx("Denied"); + } + else + { + dsq->game->bindIngredients(); + setNearestPullTarget(); + if (!pullTarget) { - TileVector tile(x,y); - if (!(tile.x == t.x && tile.y == t.y) && !dsq->game->isObstructed(tile) - && !dsq->game->isObstructed(TileVector(tile.x+1, tile.y)) - && !dsq->game->isObstructed(TileVector(tile.x, tile.y+1)) - && !dsq->game->isObstructed(TileVector(tile.x-1, tile.y)) - && !dsq->game->isObstructed(TileVector(tile.x, tile.y+1)) - ) - { - vectors.push_back(tile.worldVector()); - /* - Vector obs = tile.worldVector(); - Vector mov = position - obs; - - int len = range*TILE_SIZE - mov.getLength2D(); - if (len < 0) len = 1; - mov |= len; - total += mov; - */ - } + core->sound->playSfx("Denied"); } - } - - unsigned int amount = 5; - if (amount > vectors.size()) - amount = vectors.size(); - std::vectorsmallestDists; - smallestDists.resize(amount); - int i = 0; - for (i = 0; i < smallestDists.size(); i++) - { - smallestDists[i] = 0x7FFFFFFF; - } - std::vector closestVectors; - closestVectors.resize(amount); - for (i = 0; i < vectors.size(); i++) - { - Vector diff = dest - vectors[i]; - int dist = diff.getSquaredLength2D(); - for (int j = 0; j < smallestDists.size(); j++) - { - if (dist < smallestDists[j]) - { - for (int k = smallestDists.size()-1; k > j; k--) - { - smallestDists[k] = smallestDists[k-1]; - closestVectors[k] = closestVectors[k-1]; - } - smallestDists[j] = dist; - closestVectors[j] = vectors[i]; - } - } - } - - for (i = 0; i < closestVectors.size(); i++) - { - Vector obs = closestVectors[i]; - if (obs.x == 0 && obs.y == 0) continue; - Vector mov = obs - position; - - int len = range*TILE_SIZE - mov.getLength2D(); - if (len < 0) len = 0; else { - mov.setLength2D(len); - total += mov; + core->sound->playSfx("Bind"); } } - - if (total.x != 0 || total.y != 0) - { - //float vlen = vel.getLength2D(); - //float len = (range*TILE_SIZE - avgDist)/range*TILE_SIZE; - //if (len > 0) - { - if (bursting && swimming) - { - total.setLength2D(dt*4000); - } - else if (swimming) - { - //vel = Vector(0,0,0); - //vel |= vlen; - total.setLength2D(dt*1000); - } - else - { - total.setLength2D(dt*200); - } - vel += total; - } - /* - if (vlen < 250) - { - total |= 200*dt; - } - else - */ - /* - { - total |= 500*dt; - } - */ - - } } -void Avatar::doRangePush(float dt) +void Avatar::doShieldSong() { - // current not used - /* - if (vel.getSquaredLength2D() < sqr(1)) return; - int range = 4; - Vector total; - TileVector t(position); - std::vector vectors; - for (int x = t.x-range; x <= t.x+range; x++) - { - for (int y = t.y-range; y <= t.y+range; y++) - { - TileVector tile(x,y); - if (dsq->game->isObstructed(tile)) - { - vectors.push_back(tile.worldVector()); - } - } - } - - int amount = 5; - if (amount > vectors.size()) - amount = vectors.size(); - std::vectorsmallestDists; - smallestDists.resize(amount); - for (int i = 0; i < smallestDists.size(); i++) - { - smallestDists[i] = 0x7FFFFFFF; - } - std::vector closestVectors; - closestVectors.resize(amount); - for (int i = 0; i < vectors.size(); i++) - { - Vector diff = position - vectors[i]; - int dist = diff.getSquaredLength2D(); - for (int j = 0; j < smallestDists.size(); j++) - { - if (dist < smallestDists[j]) - { - for (int k = smallestDists.size()-1; k > j; k--) - { - smallestDists[k] = smallestDists[k-1]; - closestVectors[k] = closestVectors[k-1]; - } - smallestDists[j] = dist; - closestVectors[j] = vectors[i]; - } - } - } - - float tot=0; - int c = 0; - for (int i = 0; i < smallestDists.size(); i++) - { - if (smallestDists[i] < HUGE_VALF) - { - tot += smallestDists[i]; - c++; - } - } - float avgDist = range*TILE_SIZE; - if (c > 0) - { - avgDist = tot / c; - } - - - - for (int i = 0; i < closestVectors.size(); i++) - { - Vector obs = closestVectors[i]; - if (obs.x == 0 && obs.y == 0) continue; - Vector mov = position - obs; - - int len = range*range*TILE_SIZE - mov.getLength2D(); - if (len < 0) len = 0; - else - { - mov |= len; - total += mov; - } - } - - if (total.x != 0 || total.y != 0) - { - float vlen = vel.getLength2D(); - //float len = (range*TILE_SIZE - avgDist)/range*TILE_SIZE; - //if (len > 0) - { - float totLen = 0; - if (swimming) - { - totLen = dt*600; - } - else - { - totLen = dt*50; - } - total |= totLen; - - Vector perp = vel; - Vector n = vel; - n.normalize2D(); - float d = total.dot2D(n); - perp |= d; - total -= perp; - total |= totLen; - lastPush = total; - vel += total; - } - } - */ - + core->sound->playSfx("Shield-On"); + activateAura(AURA_SHIELD); } void Avatar::render() @@ -5866,74 +4729,11 @@ void Avatar::render() Entity::render(); - if (ropeState != 0) - { -#ifdef BBGE_BUILD_OPENGL - glPushMatrix(); - glColor4f(1.0f,0.0f,0.0f,1.0f); - glBegin(GL_LINES); - glVertex3f(position.x, position.y, 0); - glVertex3f(ropePos.x, ropePos.y, 0); - glEnd(); - glPopMatrix(); -#endif - } - - /* - if (activeAura == AURA_SHIELD) - { - glPushMatrix(); - glColor4f(0,0.5,1,1); - glTranslatef(shieldPosition.x, shieldPosition.y, 0); - drawCircle(AURA_SHIELD_RADIUS, 8); - glPopMatrix(); - } - */ - } void Avatar::onRender() { Entity::onRender(); - - /* - // HACK - if (RenderObject::renderPaths) - { - glPushMatrix(); - glLoadIdentity(); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(1, 0, 0, 0.5); - glTranslatef(400, 300, 0); - drawCircle(64); - glPopMatrix(); - } - */ - - //dsq->print(20, 600-100, "Naija: Hello there. My name is fred."); - /* - std::ostringstream os; - os << lastPush.x << ", " << lastPush.y; - debugLog(os.str()); - */ - /* - glPopMatrix(); - glPushMatrix(); - glTranslatef(position.x, position.y, position.z); - //glRotatef(0, 0, 1, -rotation.z); - glDisable(GL_BLEND); - glPointSize(12); - glDisable(GL_LIGHTING); - glColor3f(1,0,0); - glBegin(GL_LINES); - //glColor3f(1, 0, 0); - glVertex3f(0,0,0); - //glColor3f(1, 0, 0); - glVertex3f(lastPush.x*50, lastPush.y*50, 0); - glEnd(); - glPopMatrix(); - */ } int Avatar::getBeamWidth() @@ -5983,35 +4783,13 @@ int Avatar::getBeamWidth() void Avatar::onEnterState(int action) { Entity::onEnterState(action); - if (action == STATE_TRANSFORM) - { - animator.stop(); - frame = 0; - animate(anim_fish); - } - else if (action == STATE_PUSH) + if (action == STATE_PUSH) { state.lockedToWall = false; - state.crawlingOnWall = false; Animation *a = skeletalSprite.getCurrentAnimation(); if (!a || (a && a->name != "pushed")) skeletalSprite.animate("pushed", 0); } - else if (action == STATE_EATING) - { - /* - // the problems with this: - // 1. what happens out of water? - // 2. is the delay too long? - // could just play a sound and then spawn some kind of particle effect - disableInput(); - idle(); - vel=vel2=Vector(0,0); - skeletalSprite.animate("eat", 0, ANIM_OVERRIDE); - core->main(1); - enableInput(); - */ - } } void Avatar::onExitState(int action) @@ -6024,10 +4802,6 @@ void Avatar::onExitState(int action) else if (action == STATE_PUSH) { skeletalSprite.transitionAnimate("spin", 0.1); - /* - rotation.z = rotation.z+360; - rotation.interpolateTo(Vector(0,0,rotation.z-360-90), 0.5); - */ } } @@ -6092,25 +4866,6 @@ void Avatar::splash(bool down) } dsq->spawnParticleEffect("Splash", position, a); - - - //Vector(position.x, dsq->game->waterLevel.x)); - /* - Quad *splash = new Quad; - splash->setTexture("splash"); - splash->position = this->position; - splash->position.y = dsq->game->waterLevel-splash->width.x/2; - float t = 0.5; - splash->alpha.path.addPathNode(0, 0); - splash->alpha.path.addPathNode(1, 0.25); - splash->alpha.path.addPathNode(0, 1); - splash->alpha.startPath(t); - splash->scale = Vector(1.5, 0.9); - splash->scale.interpolateTo(Vector(0.5,1.2),t); - splash->setLife(1); - splash->setDecayRate(0.9); - core->getTopStateData()->addRenderObject(splash, LR_PARTICLES); - */ } void Avatar::clampVelocity() @@ -6133,10 +4888,6 @@ void Avatar::clampVelocity() } } - - - - if (!inCurrent || (inCurrent && withCurrent)) { if (dsq->continuity.form == FORM_FISH) @@ -6160,13 +4911,9 @@ void Avatar::clampVelocity() } - setMaxSpeed(currentMaxSpeed * useSpeedMult); - //float cheatLen = vel.getSquaredLength2D(); - vel.capLength2D(getMaxSpeed()); - /* - if (cheatLen > sqr(getMaxSpeed())) - vel.setLength2D(getMaxSpeed()); - */ + setMaxSpeed(currentMaxSpeed * useSpeedMult * dsq->continuity.speedMult2); + + vel.capLength2D(getMaxSpeed() /* * maxSpeedLerp.x*/); } void Avatar::activateAura(AuraType aura) @@ -6208,23 +4955,23 @@ void Avatar::updateAura(float dt) */ for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); ++i) { - //&& (*i)->life > 0.2f - if ((*i) && dsq->game->isDamageTypeEnemy((*i)->getDamageType()) && (*i)->firer != this - && (!(*i)->shotData || !(*i)->shotData->ignoreShield)) + Shot *s = *i; + if (s->isActive() && dsq->game->isDamageTypeEnemy(s->getDamageType()) && s->firer != this + && (!s->shotData || !s->shotData->ignoreShield)) { - Vector diff = (*i)->position - shieldPosition; + Vector diff = s->position - shieldPosition; if (diff.getSquaredLength2D() < sqr(AURA_SHIELD_RADIUS)) { - shieldPoints -= (*i)->getDamage(); + shieldPoints -= s->getDamage(); auraHitEmitter.start(); - dsq->spawnParticleEffect("ReflectShot", (*i)->position); + dsq->spawnParticleEffect("ReflectShot", s->position); core->sound->playSfx("Shield-Hit"); - (*i)->position += diff; - //(*i)->target = 0; - diff.setLength2D((*i)->maxSpeed); - (*i)->velocity = diff; - (*i)->reflectFromEntity(this); + s->position += diff; + //s->target = 0; + diff.setLength2D(s->maxSpeed); + s->velocity = diff; + s->reflectFromEntity(this); } } } @@ -6383,13 +5130,11 @@ void Avatar::stopBurst() //burstDelay = BURST_DELAY; burstDelay = 0; bursting = false; - animatedBurst = false; wakeEmitter.stop(); ripples = false; biteLeftEmitter.stop(); biteRightEmitter.stop(); -// lastWallJumpPos = Vector(0,0,0); } int Avatar::getCursorQuadrant() @@ -6411,7 +5156,6 @@ int Avatar::getCursorQuadrant() int Avatar::getQuadrantDirection(int lastQuad, int quad) { int diff = quad - lastQuad; - //if (lastQuad==0) return 0; if ((lastQuad==4 && quad == 1)) { diff = 1; @@ -6442,18 +5186,11 @@ void Avatar::startRoll(int dir) } Animation *a = skeletalSprite.getCurrentAnimation(); - //debugLog("start roll!"); if (!a || a->name != getRollAnimName()) { skeletalSprite.transitionAnimate(getRollAnimName(), 0.2, -1); } - /* - rollRightEmitter.load("RollRight"); - rollLeftEmitter.load("RollLeft"); - rollRightEmitter.start(); - rollLeftEmitter.start(); - */ rollRightEmitter.stop(); rollLeftEmitter.stop(); @@ -6483,23 +5220,9 @@ void Avatar::startRoll(int dir) { core->sound->fadeSfx(dsq->loops.roll, SFT_OUT, 0.5); } - /* - //HACK: make this dt based - static int rollBits = 0; - rollBits = rollBits + 1; - if (rollBits > 6) - { - if (_isUnderWater) - core->sound->playSfx("Roll2"); - rollBits = 0; - } - */ + rollDir = dir; - /* - if (core->afterEffectManager) - core->afterEffectManager->addEffect(new ShockEffect(Vector(core->width/2, core->height/2),core->screenCenter,0.04,0.06,15,0.2f)); - */ if (_isUnderWater && core->afterEffectManager) core->afterEffectManager->addEffect(new ShockEffect(Vector(core->width/2, core->height/2),core->screenCenter,0.08,0.05,22,0.2f, 1.2)); @@ -6528,8 +5251,6 @@ void Avatar::stopRoll() void Avatar::stopWallJump() { wallBurstTimer = 0; - wallJumps = 0; - lastWallJumpPos = Vector(0,0,0); } void Avatar::updateWallJump(float dt) @@ -6547,7 +5268,7 @@ void Avatar::updateWallJump(float dt) void Avatar::updateRoll(float dt) { - if (!inputEnabled || dsq->continuity.getWorldType() == WT_SPIRIT) + if (!inputEnabled || dsq->game->isWorldPaused()) { if (rolling) stopRoll(); @@ -6557,11 +5278,6 @@ void Avatar::updateRoll(float dt) if (rollDelay > 0) { - /* - std::ostringstream os; - os << "rollDelay: " << rollDelay; - debugLog(os.str()); - */ rollDelay -= dt; if (rollDelay <= 0) { @@ -6584,19 +5300,6 @@ void Avatar::updateRoll(float dt) if (rolling) { - /* - FOR_ENTITIES (i) - { - Entity *e = *i; - if (e->getEntityType() == ET_ENEMY && (e->position - this->position).isLength2DIn(350)) - { - //e->move(dt, 500, 1, this); - Vector diff = (position - e->position); - diff.setLength2D(1000*dt); - e->vel2 += diff; - } - } - */ if (dsq->continuity.form == FORM_ENERGY && dsq->continuity.hasFormUpgrade(FORMUPGRADE_ENERGY1)) { FOR_ENTITIES(i) @@ -6624,14 +5327,6 @@ void Avatar::updateRoll(float dt) } } - /* - //HACK: -ish, fixes low frame rate roll stuck problem? - // nope - if (rollDelay == 0) - { - rollDelay = 0.01; - } - */ // NOTE: does this fix the roll problem? if (rollDelay <= 0) stopRoll(); @@ -6685,19 +5380,6 @@ void Avatar::updateRoll(float dt) } } } - /* - std::ostringstream os; - os << "quad: " << quad << " lastQuad: " << lastQuad << " lastQuadDir: " << lastQuadDir; - debugLog(os.str()); - */ - - - /* - if (lastQuad != 0) - { - lastQuadDir = quadDir; - } - */ lastQuadDir = quadDir; @@ -6718,28 +5400,6 @@ int Avatar::getBurstDistance() return BURST_DISTANCE; } -void Avatar::updateTummy(float dt) -{ - if (dsq->continuity.form == FORM_BEAST) - { - //dsq->shakeCamera(5, 0.1); - - /* - if (inTummy > 0) - { - tummyTimer += dt; - if (tummyTimer > TUMMY_TIME) - { - //core->sound->playSfx("Digest"); - //heal(inTummy); - inTummy = 0; - } - } - */ - - } -} - void Avatar::setWasUnderWater() { state.wasUnderWater = isUnderWater(); @@ -6747,7 +5407,18 @@ void Avatar::setWasUnderWater() bool Avatar::canActivateStuff() { - return dsq->continuity.form != FORM_SPIRIT; + return _canActivateStuff; +} + +void Avatar::setCanActivateStuff(bool on) +{ + _canActivateStuff = on; +} + +void Avatar::setCollisionAvoidanceData(int range, float mod) +{ + _collisionAvoidRange = range; + _collisionAvoidMod = mod; } bool Avatar::canQuickSong() @@ -6884,7 +5555,6 @@ void Avatar::updateLookAt(float dt) { if (lastHeadTexture.empty()) { - //if (dsq->continuity.form == FORM_NORMAL) setHeadTexture("blink", 0.1); if (chance(50)) { @@ -6946,20 +5616,8 @@ void Avatar::updateLookAt(float dt) bone_head->rotationOffset.z = oldRot - bone_head->rotation.z; bone_head->rotationOffset.interpolateTo(Vector(0,0,0), t); bone_head->internalOffset.interpolateTo(Vector(0,0,0), t); - /* - std::ostringstream os; - os << "rotationOffset lerp " << bone_head->rotationOffset.z; - debugLog(os.str()); - */ } - /* - bone_head->rotationOffset = bone_head->rotation.z; - bone_head->rotation.z = 0; - bone_head->rotationOffset.interpolateTo(0, 0.2); - */ - //state.updateLookAtTime += dt*10; - //state.updateLookAtTime += dt; state.updateLookAtTime += dt*4*2; bone_head->internalOffset.interpolateTo(Vector(0,0), 0.2); } @@ -6969,23 +5627,7 @@ void Avatar::updateLookAt(float dt) state.lookAtEntity = dsq->game->getNearestEntity(position, 800, this, ET_NOTYPE, DT_NONE, LR_ENTITIES0, LR_ENTITIES2); if (state.lookAtEntity && state.lookAtEntity->isv(EV_LOOKAT, 1)) { - /* - std::ostringstream os; - os << "Nearest: " << state.lookAtEntity->name; - debugLog(os.str()); - */ - state.updateLookAtTime = 0; - //if (dsq->continuity.form == FORM_NORMAL) - //setHeadTexture("blink", 0.1); - - /* - if (state.lookAtEntity->getEntityType() == ET_NEUTRAL) - { - //if (dsq->continuity.form == FORM_NORMAL) - //setHeadTexture("smile", 1); - } - */ if (!state.lookAtEntity->naijaReaction.empty()) { @@ -6995,15 +5637,8 @@ void Avatar::updateLookAt(float dt) else { state.lookAtEntity = 0; - /* - std::ostringstream os; - os << state.updateLookAtTime << " : found no entities"; - debugLog(os.str()); - */ - //state.updateLookAtTime -= 0.3f; - } - //skeletalSprite.animate("blink", 2, ANIMLAYER_HEADOVERRIDE); + } } } } @@ -7020,70 +5655,13 @@ bool lastCursorKeyboard = false; bool Avatar::isMiniMapCursorOkay() { -//!(dsq->getMouseButtonState(0) || dsq->getMouseButtonState(1)) return ((dsq->inputMode != INPUT_MOUSE) || (!dsq->game->miniMapRender || !dsq->game->miniMapRender->isCursorIn())); } -void Avatar::updateCursorFromKeyboard() -{ - /* - // why return when singing?? - //if (isSinging()) return; - if (!isInputEnabled()) return; - - Vector diff; - int dist = 200; - if (isActing(ACTION_SINGLEFT)) - diff.x = -dist; - if (isActing(ACTION_SINGRIGHT)) - diff.x = dist; - if (isActing(ACTION_SINGUP)) - diff.y = -dist; - if (isActing(ACTION_SINGDOWN)) - diff.y = dist; - if (!diff.isZero()) - { - diff.setLength2D(dist); - core->mouse.position = Vector(400,300) + diff; - lastCursorKeyboard = true; - } - else if (lastCursorKeyboard) - { - debugLog("HEY!: lastCursorKeyboard mouse position reset"); - core->mouse.position = Vector(400,300); - lastCursorKeyboard = false; - dsq->toggleCursor(false, 0.2); - } - - //!diff.isZero() || - if (isInputEnabled() && (!core->mouse.change.isZero())) - { - dsq->toggleCursor(true, 0.2); - } - */ -} - void Avatar::onUpdate(float dt) { BBGE_PROF(Avatar_onUpdate); - // animation debug code - /* - for (int i = 0; i < 8; i++) - { - if (skeletalSprite.getAnimationLayer(i)) - { - if (skeletalSprite.getAnimationLayer(i)->isAnimating()) - { - std::ostringstream os; - os << "anim layer: " << i << " - " << skeletalSprite.getAnimationLayer(i)->getCurrentAnimation()->name; - debugLog(os.str()); - //debugLog("anim layer 0: " + skeletalSprite.getAnimationLayer(0)->getCurrentAnimation()->name); - } - } - } - */ - looking = 0; #ifdef AQ_TEST_QUADTRAIL @@ -7118,16 +5696,6 @@ void Avatar::onUpdate(float dt) vel = Vector(0,0); } - if (canWarpDelay > 0) - { - canWarpDelay = canWarpDelay - dt; - if (canWarpDelay < 0) - { - canWarp = true; - canWarpDelay = 0; - } - } - if (fireDelay > 0) { fireDelay -= dt; @@ -7137,13 +5705,6 @@ void Avatar::onUpdate(float dt) } } - if (doubleClickDelay > 0) - { - doubleClickDelay = doubleClickDelay - dt; - if (doubleClickDelay < 0) doubleClickDelay = 0; - } - - if (isInputEnabled()) { if (web) @@ -7177,67 +5738,6 @@ void Avatar::onUpdate(float dt) } - - // setup shader - if (core->afterEffectManager) - { - - /* - if (!_isUnderWater) - { - core->afterEffectManager->setActiveShader(AS_WASHOUT); - //core->afterEffectManager->setActiveShader(AS_NONE); - } - else - */ - if (dsq->user.video.shader != AS_NONE) - { - core->afterEffectManager->setActiveShader((ActiveShader)dsq->user.video.shader); - } - else - { - if (damageTimer.isActive() && dsq->isShakingCamera()) - { - if (dsq->user.video.blur) - core->afterEffectManager->setActiveShader(AS_BLUR); - } - else - { - core->afterEffectManager->setActiveShader(AS_NONE); - } - - } - } - - /* - if (!targets.empty()) - { - if (targets[0] && (targets[0]->position - this->position).getSquaredLength2D() > sqr(TARGET_RANGE)) - { - clearTargets(); - } - } - */ - //spawnChildClone(4); - if (!core->cameraRot.isInterpolating()) - // 10 - core->cameraRot.interpolateTo(Vector(0,0,360), 30, -1); - /* - for (int i = 0; i < targets.size(); i++) - { - if (targets[i] && !this->isEntityDead()) - { - targetQuads[i]->alpha.interpolateTo(1,0.1); - targetQuads[i]->position = targets[i]->position; - } - else - { - if (targetQuads[i]->alpha.getValue()>0) - targetQuads[i]->alpha.interpolateTo(0,0.1); - } - } - */ - Entity::onUpdate(dt); if (isEntityDead() && skeletalSprite.getCurrentAnimation()->name != "dead") @@ -7429,8 +5929,6 @@ void Avatar::onUpdate(float dt) } - //skeletalSprite.getBoneByIdx(3)->getWorldPosition(); - state.wasUnderWater = _isUnderWater; if (!_isUnderWater) @@ -7455,30 +5953,6 @@ void Avatar::onUpdate(float dt) } } - /* - if (core->afterEffectManager && _isUnderWater) - { - if (swimming && vel.getSquaredLength2D() > sqr(200)) - { - rippleTimer += dt; - while (rippleTimer > RIPPLE_INTERVAL) - { - // 0.01 20 - core->afterEffectManager->addEffect(new ShockEffect(Vector(core->width/2, core->height/2),core->screenCenter,0.05,0.08,15,0.2f, 1.2)); - - //core->afterEffectManager->addEffect(new ShockEffect(Vector(400,300),0.01,0.002f,15,0.1f)); - rippleTimer = 0; - } - } - } - */ - - - /* - bobTimer += dt*2; - offset.y = sinf(bobTimer)*5 - 2.5f; - */ - if (isEntityDead()) { updateHair(dt); @@ -7540,7 +6014,6 @@ void Avatar::onUpdate(float dt) tripDelay -= dt; if (tripDelay < 0) { -; tripDelay = 0.15; tripCount ++; if (tripCount > 10) @@ -7599,28 +6072,10 @@ void Avatar::onUpdate(float dt) lastPosition = position; } - - updateCursorFromKeyboard(); updateFormVisualEffects(dt); - updateShock(dt); updateRoll(dt); - updateTummy(dt); updateWallJump(dt); - if (dsq->autoSingMenuOpen) - { - if (micNote != -1 && !this->isSinging()) - { - openedFromMicInput = true; - openSingingInterface(); - } - if (micNote == -1 && isSinging() && openedFromMicInput) - { - openedFromMicInput = false; - closeSingingInterface(); - } - } - if (formAbilityDelay > 0) { formAbilityDelay -= dt; @@ -7645,49 +6100,6 @@ void Avatar::onUpdate(float dt) } updateAura(dt); - switch(ropeState) - { - case 1: - { - if (ropeTimer > 0) - { - ropeTimer -= dt; - if (ropeTimer < 0) - { - ropeState = 0; - ropeTimer = 0; - } - } - ropePos += ropeVel*dt; - if (dsq->game->isObstructed(TileVector(ropePos))) - { - ropeState = 2; - ropeTimer = 2; - } - std::ostringstream os; - os << "ropePos (" << ropePos.x << ", " << ropePos.y << ")"; - debugLog(os.str()); - } - break; - case 2: - if (ropeTimer > 0) - { - ropeTimer -= dt; - if (ropeTimer < 0) - { - ropeState = 0; - ropeTimer = 0; - } - } - Vector add = (ropePos - position); - if (add.getSquaredLength2D() > sqr(200)) - { - add.setLength2D(4000); - vel += add*dt; - } - break; - } - updateSingingInterface(dt); @@ -7698,53 +6110,10 @@ void Avatar::onUpdate(float dt) pullTarget->stopPull(); pullTarget = 0; } - else - { - /* - static float c = 0; - c += dt; - if (c > 0.2f) - { - EnergyTendril *t = new EnergyTendril(avatar->position, pullTarget->position); - core->addRenderObject(t, LR_PARTICLES); - c -= dt; - } - */ - } } formTimer += dt; - /* - if (formTimer > 2.0f && dsq->continuity.form == FORM_SPIRIT) - { - changeForm(FORM_NORMAL, true); - } - */ - if (pickingPullTarget) - { - //debugLog("picking pull target"); - Entity *closest = 0; - float smallestDist = HUGE_VALF; - FOR_ENTITIES(i) - { - Entity *e = *i; - - if (e->isPullable() && e->life == 1) - { - if (e->isCoordinateInside(dsq->getGameCursorPosition())) - { - float dist = (e->position - dsq->getGameCursorPosition()).getSquaredLength2D(); - if (dist < smallestDist) - { - smallestDist = dist; - closest = e; - } - } - } - } - potentialPullTarget = closest; - } if (dsq->continuity.form == FORM_SPIRIT) { @@ -7770,10 +6139,6 @@ void Avatar::onUpdate(float dt) static bool revertButtonsAreDown = false; if (inputEnabled && (dsq->inputMode == INPUT_KEYBOARD || dsq->inputMode == INPUT_MOUSE) && (!pathToActivate && !entityToActivate)) { - //debugLog("update stuff"); - ///*&& dsq->continuity.form != FORM_SPIRIT*/ - //|| isActing(ACTION_PRIMARY) - //|| isActing(ACTION_SECONDARY) if (dsq->continuity.form != FORM_NORMAL && (core->mouse.pure_buttons.left && core->mouse.pure_buttons.right) && getVectorToCursor(true).isLength2DIn(minMouse)) { if (!revertButtonsAreDown) @@ -7810,97 +6175,11 @@ void Avatar::onUpdate(float dt) revertButtonsAreDown = false; } - /* - if (this->state.crawlingOnWall) - { - if (isActing("a1")) - { - wallNormal = dsq->game->getWallNormal(position); - if (wallNormal.dot2D(lastWallNormal)<=0.3f) - { - stopWallCrawl(); - } - else - { - Vector left = wallNormal.getPerpendicularLeft(); - Vector right = wallNormal.getPerpendicularRight(); - - - Vector test = getVectorToCursor(); - if (!test.isLength2DIn(64)) - { - test.normalize2D(); - - Vector move; - if (test.dot2D(left)>0) - move = left; - else - move = right; - - move.setLength2D(800); - - if (move.x > 0 && !isfh()) - flipHorizontal(); - if (move.x < 0 && isfh()) - flipHorizontal(); - - position += move*dt; - rotateToVec(wallNormal, 0.1); - } - else - { - stopWallCrawl(); - } - } - } - else - { - stopWallCrawl(); - } - } - */ - //if (core->getNestedMains() == 1) { - if (leaches > 3) + if (getState() != STATE_TRANSFORM && !dsq->game->isWorldPaused()) { - /* - const float leachHurtInterval = 3; - state.leachTimer += dt; - if (state.leachTimer > leachHurtInterval) - { - state.leachTimer -= leachHurtInterval; - DamageData d; - d.damage = int(leaches/3); - damage(d); - //hit(0, 0, SPELL_NONE, int(leaches/3)); - } - */ - } - - - if (getState() != STATE_TRANSFORM && dsq->continuity.getWorldType() == WT_NORMAL) - //if (dsq->continuity.form == FORM_ENERGY) - { - //if (dsq->continuity.selectedSpell == SPELL_SHOCK) - formAbilityUpdate(dt); - - // is this really necessary?? - // YES! - // this allows the player to start charging quickly after firing - /* - if (isActing("charge") && !charging && spellCastDelay == 0 && inputEnabled) - { - this->rmbd(); - } - */ - // maybe not useful anymore - /* - if (!isActing("charge") && charging && spellChargeDelay == 0 && inputEnabled) - { - } - */ } if (state.useItemDelay.updateCheck(dt)) @@ -7919,29 +6198,6 @@ void Avatar::onUpdate(float dt) removeBlindEffects(); } } - - /*&& this->getSelectedSpell() == SPELL_ENERGYBLAST*/ - /* - // HACK: hacked out for now - // FINDTARGET - - if (charging && !targets.empty() && targets[0] == 0 && state.spellCharge > 0.2f - && dsq->continuity.form == FORM_ENERGY) - { - FOR_ENTITIES (i) - { - Entity *e = *i; - if (e && e != this && e->isAvatarAttackTarget() && !e->isEntityDead() && e->isAffectedBySpell(SPELL_ENERGYBLAST)) - { - ScriptedEntity *se = (ScriptedEntity*)e; - if ((e->position - dsq->getGameCursorPosition()).getSquaredLength2D() < sqr(64)) - { - targets[0] = e; - } - } - } - } - */ } @@ -7970,29 +6226,15 @@ void Avatar::onUpdate(float dt) } } - if (spellCastDelay > 0) - { - spellCastDelay -= dt; - if (spellCastDelay <= 0) - { - spellCastDelay = 0; - } - } - if (state.lockToWallDelay.updateCheck(dt)) { } - if (state.tapTimer.updateCheck(dt)) - { - tapped = ""; - } if (pushingOffWallEffect > 0) { pushingOffWallEffect -= dt; if (pushingOffWallEffect <= 0) { - lastLockToWallPos = Vector(0,0); pushingOffWallEffect = 0; if (vel.getSquaredLength2D() > sqr(1200)) { @@ -8000,61 +6242,9 @@ void Avatar::onUpdate(float dt) } } } - /* - if (beamFiring) - { - // collides enemies with beam as well - beam->width = getBeamWidth(); - Vector diff = dsq->getGameCursorPosition() - this->position; - diff |= beam->width.getValue()/2.0f; - beam->position = this->position + diff; - float angle=0; - MathFunctions::calculateAngleBetweenVectorsInDegrees(this->position, dsq->getGameCursorPosition(), angle); - beam->rotation.z = angle+90; - beam->position.z = 3; - //collideBeamWithEntities(); - } - */ - if (state.dodgeEffectTimer.updateCheck(dt)) - { - vel.capLength2D(vars->maxSwimSpeed); - /* - if (vel.getSquaredLength2D() > sqr(vars->maxSwimSpeed)) - vel.setLength2D(vars->maxSwimSpeed); - */ - } - /* - if (dodgeEffectTimer > 0) - { - dodgeEffectTimer -= dt; - if (dodgeEffectTimer <= 0) - { - dodgeEffectTimer = 0; - if (vel.getSquaredLength2D() > sqr(vars->maxSwimSpeed)) - vel |= vars->maxSwimSpeed; - } - } - */ - if (dodgeDelay > 0) - { - dodgeDelay -= dt; - if (dodgeDelay <= 0) - { - dodgeDelay = 0; - } - } - - if (text) - { - text->position = position + Vector(100); - } if (charging) { - /* - chargeGraphic->position = this->position; - chargeGraphic->position.z = position.z + 0.05f; - */ state.spellCharge += dt; switch (dsq->continuity.form) { @@ -8081,37 +6271,11 @@ void Avatar::onUpdate(float dt) chargingEmitter->load("ChargedDualForm"); chargingEmitter->start(); - - - - //chargeVisualEffect("particles/energy-charge-2"); } - /* - if (state.spellCharge >= 1.5f && chargeLevelAttained<2) - { - chargeLevelAttained = 2; - - core->sound->playSfx("PowerUp"); - //debugLog("charge visual effect 2"); - chargeEmitter->load("EnergyCharge"); - chargeEmitter->start(); - - //chargeVisualEffect("particles/energy-charge-2"); - } - */ } break; case FORM_ENERGY: { - /* - if (state.spellCharge >= 0.99f && chargeLevelAttained<1) - { - chargeLevelAttained = 1; - debugLog("charge visual effect 1"); - chargeVisualEffect("energy-charge-1"); - - } - */ if (state.spellCharge >= 1.5f && chargeLevelAttained<2) { chargeLevelAttained = 2; @@ -8138,26 +6302,6 @@ void Avatar::onUpdate(float dt) chargingEmitter->load("ChargingNature2"); chargingEmitter->start(); } - /* - if (state.spellCharge >= 0.5f && chargeLevelAttained<1) - { - chargeLevelAttained = 1; - core->sound->playSfx("PowerUp"); - chargeEmitter->load("ChargeNature"); - chargeEmitter->start(); - } - - if (state.spellCharge >= 2.0f && chargeLevelAttained<2) - { - chargeLevelAttained = 2; - core->sound->playSfx("PowerUp"); - chargeEmitter->load("ChargeNature2"); - chargeEmitter->start(); - - chargingEmitter->load("ChargingNature2"); - chargingEmitter->start(); - } - */ } break; } @@ -8267,7 +6411,7 @@ void Avatar::onUpdate(float dt) } } - if (!(state.lockedToWall || state.dodgeEffectTimer.isActive()) && _isUnderWater && dsq->continuity.getWorldType() == WT_NORMAL && canMove) + if (!state.lockedToWall && _isUnderWater && !dsq->game->isWorldPaused() && canMove) { if (bursting) { @@ -8290,18 +6434,8 @@ void Avatar::onUpdate(float dt) } if (inputEnabled && _isUnderWater) { - if (bursting) + if(bursting) { - // disable check to stop burst - /* - if (!isActing("a1")) - { - stopBurst(); - //bursting = false; - //burstDelay = BURST_DELAY; - //animatedBurst = false; - } - */ } else if (burstDelay > 0) { @@ -8320,7 +6454,7 @@ void Avatar::onUpdate(float dt) bool moved = false; //check to make sure there's still a wall there, if not fall off - if (state.lockedToWall && !state.crawlingOnWall) + if (state.lockedToWall) { rotateToVec(wallPushVec, dt*2); if (!boneLock.on && !dsq->game->isObstructed(wallLockTile)) @@ -8330,27 +6464,19 @@ void Avatar::onUpdate(float dt) } } - if (getState() != STATE_PUSH && !state.lockedToWall && inputEnabled && !ignoreInputDelay && _isUnderWater && canMove) + if (getState() != STATE_PUSH && !state.lockedToWall && inputEnabled && _isUnderWater && canMove) { float a = 800*dt; - Vector lastVel = vel; Vector addVec; bool isMovingSlow = false; - static Vector lastMousePos; - Vector pos = lastMousePos - dsq->getGameCursorPosition(); - static bool lastDown; float len = 0; - //dsq->continuity.toggleMoveMode && - //!dsq->continuity.toggleMoveMode && if (isMiniMapCursorOkay() && !isActing(ACTION_ROLL) && _isUnderWater && !riding && !boneLock.on && (movingOn || ((dsq->inputMode == INPUT_JOYSTICK || dsq->inputMode== INPUT_KEYBOARD) || (core->mouse.buttons.left || bursting)))) { - //addVec = getVectorToCursorFr - //(dsq->inputMode != INPUT_JOYSTICK && dsq->inputMode != INPUT_KEYBOARD) if (dsq->inputMode == INPUT_MOUSE || !this->singing) { addVec = getVectorToCursorFromScreenCentre();//getVectorToCursor(); @@ -8373,31 +6499,13 @@ void Avatar::onUpdate(float dt) { if (dsq->inputMode == INPUT_JOYSTICK) addVec = Vector(0,0,0); - /* - if (dsq->inputMode == INPUT_JOYSTICK && !core->mouse.buttons.left) - { - addVec = Vector(0,0,0); - } - */ } - - - /* - if (!core->mouse.buttons.left && bursting) - { - addVec = vel; - } - */ - if (!addVec.isLength2DIn(minMouse)) { //if (core->mouse.buttons.left) { len = addVec.getLength2D(); - // addVec is always overwritten below; I assume this is old code? --achurch - //if (len > 200) - // addVec.setLength2D(a *10); if (len > 100) addVec.setLength2D(a *2); else @@ -8431,31 +6539,11 @@ void Avatar::onUpdate(float dt) stopBurst(); } } - //vel = Vector(0,0,0); } addVec = Vector(0,0,0); } } - - //addVec |= a; - /* - if (pos.getSquaredLength2D() > 10000) - { - startBurst(); - } - */ } - else - { - } - lastDown = core->mouse.buttons.left; - - /* - std::ostringstream os; - os << "addVec(" << addVec.x << ", " << addVec.y << ")"; - debugLog(os.str()); - */ - lastMousePos = dsq->getGameCursorPosition(); if (!rolling && !state.backFlip && !flourish) { @@ -8488,20 +6576,6 @@ void Avatar::onUpdate(float dt) } } - - /* - // HACK: joystick code / slow - if (addVec.x == 0 && addVec.y == 0) - { - float jpos[2]; - glfwGetJoystickPos(GLFW_JOYSTICK_1, jpos, 2); - const float deadZone = 0.1; - if (fabsf(jpos[0]) > deadZone || fabsf(jpos[1]) > deadZone) - addVec = Vector(jpos[0]*a, -jpos[1]*a); - } - */ - - // will not get here if not underwater if (isLockable()) lockToWall(); @@ -8509,23 +6583,15 @@ void Avatar::onUpdate(float dt) { currentMaxSpeed=0; vel += addVec; - //addVec |= a; - //float cheatLen = vel.getSquaredLength2D(); + if (bursting) { Vector add = addVec; - /* - // HACK: this will let the player boost in one direction while turning to face another - if (!core->mouse.buttons.left) - { - add = vel; - } - */ add.setLength2D(BURST_ACCEL*dt); vel += add; - if (pushingOffWallEffect > 0 || wallJumps > 0) - currentMaxSpeed = vars->maxWallJumpBurstSpeed + 50*wallJumps; + if (pushingOffWallEffect > 0) + currentMaxSpeed = vars->maxWallJumpBurstSpeed; else currentMaxSpeed = vars->maxBurstSpeed; @@ -8534,39 +6600,20 @@ void Avatar::onUpdate(float dt) { if (pushingOffWallEffect > 0) currentMaxSpeed = vars->maxWallJumpSpeed; - else if (state.dodgeEffectTimer.isActive()) - currentMaxSpeed = vars->maxDodgeSpeed; else { if (isActing(ACTION_SLOW) || isMovingSlow) { - /* - int spdRange = maxMouse - minMouse; - float p = (len - minMouse) / spdRange; - int spd = p * vars->maxSwimSpeed;// + minMouse - currentMaxSpeed = spd; - */ currentMaxSpeed = vars->maxSlowSwimSpeed; } - //else if (dsq->continuity.getWorldType() == WT_NORMAL) else currentMaxSpeed = vars->maxSwimSpeed; - /* - else - currentMaxSpeed = vars->maxDreamWorldSpeed; - */ } } - /* - if (dsq->continuity.form == FORM_SPIRIT) - currentMaxSpeed *= 0.5f; - */ - if (leaches > 0) { currentMaxSpeed -= leaches*60; - // vel |= vel.getLength2D()-1*leaches; } if (state.blind) @@ -8575,22 +6622,6 @@ void Avatar::onUpdate(float dt) if (currentMaxSpeed < 0) currentMaxSpeed = 1; - if (ropeState == 2 && currentMaxSpeed < vars->maxWallJumpBurstSpeed) - currentMaxSpeed = vars->maxWallJumpBurstSpeed; - - /* - if (inCurrent) - { - ropeState = 0; - currentMaxSpeed = 1200; - } - */ - - //clampVelocity(); - - - //float angle; - if (getState() == STATE_TRANSFORM) rotateToVec(addVec, 0.1, 90); else @@ -8618,13 +6649,6 @@ void Avatar::onUpdate(float dt) } else { - /* - if (bursting && !core->mouse.buttons.left) - { - } - else - rotateToVec(addVec, 0.1); - */ if (!state.nearWall && !flourish) rotateToVec(addVec, 0.1); } @@ -8662,8 +6686,6 @@ void Avatar::onUpdate(float dt) { if (getState() == STATE_IDLE && !rolling) skeletalSprite.transitionAnimate(getBurstAnimName(), ANIM_TRANSITION); - //animate(anim_burst); - animatedBurst = true; } } } @@ -8719,19 +6741,6 @@ void Avatar::onUpdate(float dt) } if (isLockable()) lockToWall(); - /* - if (isActing("left")) - addVec += Vector(-a, 0); - if (isActing("right")) - addVec += Vector(a, 0); - */ - /* - if (isActing("up")) - addVec += Vector(0, -a); - if (isActing("down")) - addVec += Vector(0, a); - */ - //vel += addVec; } if (!moved) @@ -8739,7 +6748,6 @@ void Avatar::onUpdate(float dt) if (swimming) { swimming = false; - idleAnimDelay = 0; if (dsq->continuity.form == FORM_FISH) rotation.interpolateTo(0, 0.2); } @@ -8788,9 +6796,6 @@ void Avatar::onUpdate(float dt) if (!inCurrent) currentMaxSpeed = vars->maxSwimSpeed; - if (ropeState == 2 && currentMaxSpeed < vars->maxWallJumpBurstSpeed) - currentMaxSpeed = vars->maxWallJumpBurstSpeed; - if (!state.lockedToWall && !bursting) { if (getState() == STATE_IDLE && inputEnabled) @@ -8799,22 +6804,6 @@ void Avatar::onUpdate(float dt) if (a && a->name != getIdleAnimName() && a->name != "pushed" && a->name != "spin" && !rolling) skeletalSprite.transitionAnimate(getIdleAnimName(), ANIM_TRANSITION, -1); } - /* - idleAnimDelay -= dt; - if (idleAnimDelay <= 0) - { - idleAnimDelay = 1.5;//anim_idle.time*2; - - //if (currentAction == IDLE && (!skeletalSprite.isAnimating() || skeletalSprite.getCurrentAnimation()->name=="swim" - // || skeletalSprite.getCurrentAnimation()->name=="a1")) - if (currentAction == STATE_IDLE) - { - skeletalSprite.transitionAnimate("idle", ANIM_TRANSITION); - } - - //animate(anim_idle); - } - */ } } @@ -8832,7 +6821,6 @@ void Avatar::onUpdate(float dt) if (swimming) { - //static bool lastSpreadUp = false; if (!rolling && !internalOffset.isInterpolating()) { int spread = 8; @@ -8842,25 +6830,10 @@ void Avatar::onUpdate(float dt) internalOffset = Vector(-spread, 0); internalOffset.interpolateTo(Vector(spread, 0), t, -1, 1, 1); - /* - rotationOffset = Vector(-rotSpread, 0); - rotationOffset.interpolateTo(Vector(rotSpread, 0), t, -1, 1, 1); - */ - for (int i = 0; i < int((t*0.5f)/0.01f); i++) { internalOffset.update(0.01); - //rotationOffset.update(0.01); } - /* - if (lastSpreadUp) - internalOffset.interpolateTo(Vector(spread, 0), t, 1, 1, 1); - else - internalOffset.interpolateTo(Vector(-spread, 0), t, 1, 1, 1); - */ - - //lastSpreadUp = !lastSpreadUp; - //internalOffset.update(t*0.5f); } if (dsq->continuity.form != FORM_ENERGY && dsq->continuity.form != FORM_DUAL && dsq->continuity.form != FORM_FISH) @@ -8985,29 +6958,11 @@ void Avatar::onUpdate(float dt) } - if (state.dodgeEffectTimer.isActive()) + if (!state.lockedToWall && !bursting && _isUnderWater && swimming && !isFollowingPath() && _collisionAvoidRange > 0) { - vel += dodgeVec*dt; + doCollisionAvoidance(dt, _collisionAvoidRange, _collisionAvoidMod, 0, 800, OT_HURT); } - if (!state.lockedToWall && !bursting && _isUnderWater && swimming && !isFollowingPath()) - { - //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); - } - - // friction for extraVel - if (!extraVel.isZero()) - { - Vector d = extraVel; - d.setLength2D(100); - extraVel -= d*dt; - } - - if (!game->isShuttingDownGameState()) { updateCurrents(dt); @@ -9018,20 +6973,15 @@ void Avatar::onUpdate(float dt) vel2 = Vector(0,0,0); } - //int collideCircle = 24;//24; // 48 - int collideCircle = 10; - if (dsq->continuity.form == FORM_FISH) - collideCircle = 8; - // just for external access - // HACK: should always be using collide radius :| ? - - //updateMovement - collideRadius = collideCircle; if (!state.lockedToWall && !isFollowingPath() && !riding) { /*collideCheck:*/ - if (vel.getLength2D() < sqr(2)) + // Beware: This code may cause clamping vel to zero if the framerate is very high. + // Starting with zero vel, low difftimes will cause an addVec small enough that this + // check will always trigger, and vel will never get larger than zero. + // Under water and swimming check should hopefully prevent this from happening. -- FG + if (_isUnderWater && !isSwimming() && vel.getLength2D() < sqr(2)) { vel = Vector(0,0,0); } @@ -9053,7 +7003,7 @@ void Avatar::onUpdate(float dt) os << "vel (" << vel.x << ", " << vel.y << ")"; debugLog(os.str()); */ - Vector mov = (moveVel * dt) + (extraVel * dt); + Vector mov = (moveVel * dt); Vector omov = mov; mov.capLength2D(TILE_SIZE); /* @@ -9072,23 +7022,19 @@ void Avatar::onUpdate(float dt) else omov -= mov; - lastLastPosition = position; lastPosition = position; Vector newPosition = position + mov; //Vector testPosition = position + (vel *dt)*2; position = newPosition; - - int hw = collideCircle; - - if (dsq->game->collideCircleWithGrid(position, hw)) + 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); @@ -9186,19 +7132,6 @@ void Avatar::onUpdate(float dt) // && dsq->game->getPercObsInArea(position, 4) < 0.75f if (!inCurrent) { - /* - int px=int(position.x); - int py=int(position.y); - int llpx=int(lastLastPosition.x); - int llpy=int(lastLastPosition.y); - if (px == llpx && py == llpy) - { - - } - else - { - */ - //doBounce(); if (bursting) { //vel = 0; @@ -9227,7 +7160,6 @@ void Avatar::onUpdate(float dt) //vel = (n + vel)*0.5f; } } - //} } } } @@ -9246,39 +7178,6 @@ void Avatar::onUpdate(float dt) } } } - - /* - if (swimming) - { - int px=int(position.x); - int py=int(position.y); - int llpx=int(lastLastPosition.x); - int llpy=int(lastLastPosition.y); - if (px == llpx && py == llpy) - { - if (isNearObstruction(4)) - { - vel = 0; - Vector n = dsq->game->getWallNormal(position, 6); - if (!n.isZero()) - { - Vector add = n * 100; - Vector f = getForward(); - n = (n + f * 100); - n *= 0.5f; - vel += n; - } - } - } - } - */ - - if (ignoreInputDelay>0) - { - ignoreInputDelay -= dt; - if (ignoreInputDelay < 0) - ignoreInputDelay = 0; - } } //fuuugly @@ -9298,7 +7197,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)); } @@ -9308,23 +7208,6 @@ void Avatar::checkNearWall() if (!inCurrent && bursting && !state.lockedToWall && !vel.isZero() && !riding && _isUnderWater) { - /* - int mult = 1; - if (isfh()) - mult = -1; - */ - /* - Vector n = dsq->game->getWallNormal(position, 8); - if (!n.isZero()) - { - state.nearWall = true; - float t=0.2; - rotateToVec(n, t, 0); - skeletalSprite.transitionAnimate("wall", t); - } - else - state.nearWall = false; - */ int checkRange = 11; Vector v = vel; v.normalize2D(); @@ -9335,7 +7218,7 @@ void Avatar::checkNearWall() { t.x = oT.x + v.x*i; t.y = oT.y + v.y*i; - if (dsq->game->isObstructed(t) && dsq->game->getGrid(t) != OT_HURT) + if (dsq->game->isObstructed(t, ~OT_HURT)) { obs = true; break; @@ -9362,32 +7245,6 @@ void Avatar::checkNearWall() } } -void Avatar::checkSpecial() -{ - /* - if (dsq->continuity.getFlag("VedhaFollow1") == 7) - { - int total = 0, c = 0; - FOR_ENTITIES (i) - { - Entity *e = *i; - if (e->name == "PracticeEnemy") - { - total++; - if (e->isEntityDead()) - c++; - } - } - if (total == c) - { - health = maxHealth; - dsq->continuity.setFlag("VedhaFollow1", 8); - dsq->getEntityByName("Vedha")->activate(); - } - } - */ -} - void Avatar::onWarp() { avatar->setv(EV_NOINPUTNOVEL, 0); diff --git a/Aquaria/Avatar.h b/Aquaria/Avatar.h index b4232f5..0287a1d 100644 --- a/Aquaria/Avatar.h +++ b/Aquaria/Avatar.h @@ -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 songIcons; - std::vector formIcons; - //std::vector 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 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; }; 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 8d4190c..18ae971 100644 --- a/Aquaria/Continuity.cpp +++ b/Aquaria/Continuity.cpp @@ -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++) 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 41e31d2..f9bd757 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -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(); - } -} diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 48ef1f2..68533b9 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -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 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; - 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; - - 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; diff --git a/Aquaria/Entity.cpp b/Aquaria/Entity.cpp index 54a4e9a..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() { @@ -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; +} diff --git a/Aquaria/Entity.h b/Aquaria/Entity.h index cc4d125..70c7a51 100644 --- a/Aquaria/Entity.h +++ b/Aquaria/Entity.h @@ -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 NodeGroup; - typedef std::map 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: diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 68d699b..1520c8d 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -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 &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"); diff --git a/Aquaria/Game.h b/Aquaria/Game.h index c7789ee..3585cca 100644 --- a/Aquaria/Game.h +++ b/Aquaria/Game.h @@ -125,7 +125,6 @@ typedef std::vector 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 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 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/GameplayVariables.cpp b/Aquaria/GameplayVariables.cpp index bd04c5d..8d7bfcd 100644 --- a/Aquaria/GameplayVariables.cpp +++ b/Aquaria/GameplayVariables.cpp @@ -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; 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..ef791f0 100644 --- a/Aquaria/Ingredient.cpp +++ b/Aquaria/Ingredient.cpp @@ -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); diff --git a/Aquaria/Main.cpp b/Aquaria/Main.cpp index 215c659..290e54d 100644 --- a/Aquaria/Main.cpp +++ b/Aquaria/Main.cpp @@ -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(); 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..4a38b9c 100644 --- a/Aquaria/Mod.cpp +++ b/Aquaria/Mod.cpp @@ -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) diff --git a/Aquaria/Network.cpp b/Aquaria/Network.cpp index 6dba942..e1358f5 100644 --- a/Aquaria/Network.cpp +++ b/Aquaria/Network.cpp @@ -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); 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/SceneEditor.cpp b/Aquaria/SceneEditor.cpp index bfe068d..cf173fb 100644 --- a/Aquaria/SceneEditor.cpp +++ b/Aquaria/SceneEditor.cpp @@ -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; diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 303e3af..6c7483f 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -34,6 +34,7 @@ extern "C" #include "Entity.h" #include "Web.h" #include "GridRender.h" +#include "AfterEffect.h" #include "../BBGE/MathFunctions.h" @@ -75,6 +76,7 @@ static const char * const interfaceFunctions[] = { "activate", "animationKey", "castSong", + "cookFailure", "damage", "deathNotify", "dieEaten", @@ -83,6 +85,7 @@ static const char * const interfaceFunctions[] = { "entityDied", "exitState", "exitTimer", + "getIngredientEffectString", "hitEntity", "hitSurface", "init", @@ -97,6 +100,7 @@ static const char * const interfaceFunctions[] = { "songNoteDone", "sporesDropped", "update", + "useIngredient", "useTreasure", NULL }; @@ -360,7 +364,7 @@ static void scriptError(lua_State *L, const std::string& msg) // - The C++ standard allows offsetof() only on POD-types. Oh well, it probably works anyways. // If it does not compile for some reason, comment it out, hope for the best, and go ahead. #if !(defined(__GNUC__) && __GNUC__ <= 2) -void compile_time_assertions() +static void compile_time_assertions() { #define oo(cls) offsetof(cls, _objtype) compile_assert(oo(Path) == oo(RenderObject)); @@ -376,6 +380,7 @@ void compile_time_assertions() compile_assert(oo(Path) == oo(Quad)); compile_assert(oo(Path) == oo(Avatar)); compile_assert(oo(Path) == oo(BaseText)); + compile_assert(oo(Path) == oo(PauseQuad)); #undef oo } #endif @@ -456,6 +461,12 @@ std::string getString(lua_State *L, int slot = 1) return sr; } +static inline +const char *getCString(lua_State *L, int slot = 1) +{ + return lua_isstring(L, slot) ? lua_tostring(L, slot) : NULL; +} + static inline Shot *getShot(lua_State *L, int slot = 1) { @@ -577,6 +588,16 @@ BaseText *getText(lua_State *L, int slot = 1) return q; } +static inline +Shader *getShader(lua_State *L, int slot = 1) +{ + Shader *q = (Shader*)lua_touserdata(L, slot); + ENSURE_TYPE(q, SCO_SHADER); + if (!q) + scriptDebug(L, "Invalid Shader"); + return q; +} + static SkeletalSprite *getSkeletalSprite(Entity *e) { return e ? &e->skeletalSprite : NULL; @@ -692,8 +713,9 @@ luaFunc(indexWarnInstance) luaFunc(panicHandler) { - errorLog(luaFormatStackInfo(L) + ": Lua PANIC: " + getString(L, -1)); - exit(1); + std::string err = luaFormatStackInfo(L) + ": Lua PANIC: " + getString(L, -1); + exit_error(err); + return 0; } static bool findFile_helper(const char *rawname, std::string &fname) @@ -846,6 +868,12 @@ luaFunc(obj_alphaMod) luaReturnNil() } +luaFunc(obj_getAlphaMod) +{ + RenderObject *r = robj(L); + luaReturnNum(r ? r->alphaMod : 0.0f); +} + luaFunc(obj_getAlpha) { RenderObject *r = robj(L); @@ -864,6 +892,16 @@ luaFunc(obj_color) luaReturnNil(); } +luaFunc(obj_getColor) +{ + RenderObject *r = robj(L); + Vector c; + if(r) + c = r->color; + luaReturnVec3(c.x, c.y, c.z); +} + + luaFunc(obj_rotate) { RenderObject *r = robj(L); @@ -1261,12 +1299,18 @@ luaFunc(obj_setLayer) luaReturnNil(); } +luaFunc(obj_getLayer) +{ + RenderObject *r = robj(L); + luaReturnInt(r ? r->layer : 0); +} + luaFunc(obj_setRenderPass) { RenderObject *r = robj(L); int pass = lua_tointeger(L, 2); if (r) - r->setOverrideRenderPass(pass); + r->setRenderPass(pass); luaReturnNil(); } @@ -1451,6 +1495,18 @@ luaFunc(quad_setVisible) luaReturnNil(); } +luaFunc(quad_getWidth) +{ + Quad *q = getQuad(L); + luaReturnNum(q ? q->width : 0.0f); +} + +luaFunc(quad_getHeight) +{ + Quad *q = getQuad(L); + luaReturnNum(q ? q->height : 0.0f); +} + luaFunc(quad_setWidth) { Quad *q = getQuad(L); @@ -1467,6 +1523,14 @@ luaFunc(quad_setHeight) luaReturnNil(); } +luaFunc(quad_setSegs) +{ + Quad *b = getQuad(L); + if (b) + b->setSegs(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7), lua_tonumber(L, 8), lua_tointeger(L, 9)); + luaReturnNil(); +} + // --- standard set/get functions for each type, wrapping RenderObject functions --- @@ -1490,7 +1554,9 @@ luaFunc(quad_setHeight) RO_FUNC(getter, prefix, alpha ) \ RO_FUNC(getter, prefix, alphaMod ) \ RO_FUNC(getter, prefix, getAlpha ) \ + RO_FUNC(getter, prefix, getAlphaMod ) \ RO_FUNC(getter, prefix, color ) \ + RO_FUNC(getter, prefix, getColor ) \ RO_FUNC(getter, prefix, rotate ) \ RO_FUNC(getter, prefix, rotateOffset ) \ RO_FUNC(getter, prefix, getRotation ) \ @@ -1507,6 +1573,7 @@ luaFunc(quad_setHeight) RO_FUNC(getter, prefix, setBlendType ) \ RO_FUNC(getter, prefix, setTexture ) \ RO_FUNC(getter, prefix, delete ) \ + RO_FUNC(getter, prefix, getLife ) \ RO_FUNC(getter, prefix, setLife ) \ RO_FUNC(getter, prefix, setDecayRate ) \ RO_FUNC(getter, prefix, addDeathNotify ) \ @@ -1530,6 +1597,7 @@ luaFunc(quad_setHeight) RO_FUNC(getter, prefix, moveToFront ) \ RO_FUNC(getter, prefix, moveToBack ) \ RO_FUNC(getter, prefix, setLayer ) \ + RO_FUNC(getter, prefix, getLayer ) \ RO_FUNC(getter, prefix, setRenderBeforeParent) \ RO_FUNC(getter, prefix, addChild ) \ RO_FUNC(getter, prefix, fh ) \ @@ -1550,6 +1618,7 @@ luaFunc(quad_setHeight) 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 ) @@ -1558,7 +1627,10 @@ luaFunc(quad_setHeight) Q_FUNC(getter, prefix, setVisible ) \ Q_FUNC(getter, prefix, isVisible ) \ Q_FUNC(getter, prefix, setWidth ) \ - Q_FUNC(getter, prefix, setHeight ) + Q_FUNC(getter, prefix, setHeight ) \ + Q_FUNC(getter, prefix, getWidth ) \ + Q_FUNC(getter, prefix, getHeight ) \ + Q_FUNC(getter, prefix, setSegs ) // This should reflect the internal class hierarchy, // e.g. a Beam is a Quad, so it can use quad_* functions @@ -1571,7 +1643,7 @@ luaFunc(quad_setHeight) MAKE_ROBJ_FUNCS(getWeb, web ) \ MAKE_ROBJ_FUNCS(getText, text ) -// first time, create them. (There is a second use of this further down, with differet MK_* macros) +// first time, create them. (There is a second use of this further down, with different MK_* macros) EXPAND_FUNC_PROTOTYPES @@ -1670,7 +1742,8 @@ luaFunc(hasFormUpgrade) luaReturnBool(dsq->continuity.hasFormUpgrade((FormUpgradeType)lua_tointeger(L, 1))); } -luaFunc(castSong) +// This used to be castSong(), but that name is already taken by an interface function. -- FG +luaFunc(singSong) { dsq->continuity.castSong(lua_tonumber(L, 1)); luaReturnNil(); @@ -1795,6 +1868,22 @@ luaFunc(web_getNumPoints) luaReturnInt(num); } +luaFunc(getFirstShot) +{ + luaReturnPtr(Shot::getFirstShot()); +} + +luaFunc(getNextShot) +{ + luaReturnPtr(Shot::getNextShot()); +} + +luaFunc(shot_getName) +{ + Shot *s = getShot(L); + luaReturnStr(s ? s->getName() : ""); +} + luaFunc(shot_setOut) { Shot *shot = getShot(L); @@ -1825,6 +1914,79 @@ luaFunc(shot_setAimVector) luaReturnNil(); } +luaFunc(shot_getEffectTime) +{ + Shot *shot = getShot(L); + luaReturnNum((shot && shot->shotData) ? shot->shotData->effectTime : 0.0f); +} + +luaFunc(shot_isIgnoreShield) +{ + Shot *shot = getShot(L); + luaReturnBool((shot && shot->shotData) ? shot->shotData->ignoreShield : false); +} + +luaFunc(shot_getFirer) +{ + Shot *shot = getShot(L); + luaReturnPtr(shot ? shot->firer : NULL); +} + +luaFunc(shot_setFirer) +{ + Shot *shot = getShot(L); + if(shot) + { + Entity *e = lua_isuserdata(L, 2) ? entity(L, 2) : NULL; + shot->firer = e; + } + + luaReturnNil(); +} + +luaFunc(shot_setTarget) +{ + Shot *shot = getShot(L); + if(shot) + { + Entity *e = lua_isuserdata(L, 2) ? entity(L, 2) : NULL; + shot->setTarget(e); + } + luaReturnNil(); +} + +luaFunc(shot_getTarget) +{ + Shot *shot = getShot(L); + luaReturnPtr(shot ? shot->target : NULL); +} + +luaFunc(shot_setExtraDamage) +{ + Shot *shot = getShot(L); + if(shot) + shot->extraDamage = lua_tonumber(L, 2); + luaReturnNil(); +} + +luaFunc(shot_getExtraDamage) +{ + Shot *shot = getShot(L); + luaReturnNum(shot ? shot->extraDamage : 0.0f); +} + +luaFunc(shot_getDamage) +{ + Shot *shot = getShot(L); + luaReturnNum(shot ? shot->getDamage() : 0.0f); +} + +luaFunc(shot_getDamageType) +{ + Shot *shot = getShot(L); + luaReturnNum(shot ? shot->getDamageType() : DT_NONE); +} + luaFunc(entity_setVel) { Entity *e = entity(L); @@ -1990,18 +2152,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); @@ -2225,6 +2391,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); @@ -2321,7 +2506,7 @@ luaFunc(entity_findNearestEntityOfType) Entity *nearest = 0; if (e) { - int et = (EntityType)lua_tointeger(L, 2); + EntityType et = (EntityType)lua_tointeger(L, 2); int maxRange = lua_tointeger(L, 3); float smallestDist = HUGE_VALF; Entity *closest = 0; @@ -2420,6 +2605,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); @@ -2431,6 +2624,12 @@ luaFunc(entity_setFillGrid) luaReturnNil(); } +luaFunc(entity_isFillGrid) +{ + Entity *e = entity(L); + luaReturnBool(e ? e->fillGridFromQuad : false); +} + luaFunc(entity_getAimVector) { Entity *e = entity(L); @@ -2557,6 +2756,69 @@ luaFunc(avatar_setCanDie) luaReturnNil(); } +// not naming this avatar_* because it rather belongs into the UI category... +luaFunc(setCanActivate) +{ + dsq->game->avatar->setCanActivateStuff(getBool(L, 1)); + luaReturnNil(); +} + +luaFunc(setSeeMapMode) +{ + dsq->game->avatar->setSeeMapMode((SeeMapMode)lua_tointeger(L, 1)); + luaReturnNil(); +} + +luaFunc(avatar_setCanBurst) +{ + dsq->game->avatar->setCanBurst(getBool(L, 1)); + luaReturnNil(); +} + +luaFunc(avatar_canBurst) +{ + luaReturnBool(dsq->game->avatar->canBurst()); +} + +luaFunc(avatar_setCanLockToWall) +{ + dsq->game->avatar->setCanLockToWall(getBool(L, 1)); + luaReturnNil(); +} + +luaFunc(avatar_canLockToWall) +{ + luaReturnBool(dsq->game->avatar->canLockToWall()); +} + +luaFunc(avatar_setCanSwimAgainstCurrents) +{ + dsq->game->avatar->setCanSwimAgainstCurrents(getBool(L, 1)); + luaReturnNil(); +} + +luaFunc(avatar_canSwimAgainstCurrents) +{ + luaReturnBool(dsq->game->avatar->canSwimAgainstCurrents()); +} + +luaFunc(avatar_setCanCollideWithShots) +{ + dsq->game->avatar->setCollideWithShots(getBool(L, 1)); + luaReturnNil(); +} + +luaFunc(avatar_canCollideWithShots) +{ + luaReturnBool(dsq->game->avatar->canCollideWithShots()); +} + +luaFunc(avatar_setCollisionAvoidanceData) +{ + dsq->game->avatar->setCollisionAvoidanceData(lua_tointeger(L, 1), lua_tonumber(L, 2)); + luaReturnNil(); +} + luaFunc(avatar_toggleCape) { dsq->game->avatar->toggleCape(getBool(L,1)); @@ -2571,6 +2833,11 @@ luaFunc(avatar_setBlockSinging) luaReturnNil(); } +luaFunc(avatar_isBlockSinging) +{ + luaReturnBool(dsq->game->avatar->isBlockSinging()); +} + luaFunc(avatar_fallOffWall) { dsq->game->avatar->fallOffWall(); @@ -2604,6 +2871,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()); @@ -2622,6 +2899,28 @@ luaFunc(avatar_getSpellCharge) luaReturnNum(dsq->game->avatar->state.spellCharge); } +luaFunc(avatar_setSpeedMult) +{ + dsq->continuity.setSpeedMultiplier(lua_tonumber(L, 1), lua_tonumber(L, 2)); + luaReturnNil(); +} + +luaFunc(avatar_setSpeedMult2) +{ + dsq->continuity.speedMult2 = lua_tonumber(L, 1); + luaReturnNil(); +} + +luaFunc(avatar_getSpeedMult) +{ + luaReturnNum(dsq->continuity.speedMult); +} + +luaFunc(avatar_getSpeedMult2) +{ + luaReturnNum(dsq->continuity.speedMult2); +} + luaFunc(jumpState) { dsq->enqueueJumpState(getString(L, 1), getBool(L, 2)); @@ -2724,11 +3023,6 @@ luaFunc(entity_followPath) luaReturnNil(); } -luaFunc(getIngredientGfx) -{ - luaReturnStr(dsq->continuity.getIngredientGfx(getString(L, 1)).c_str()); -} - luaFunc(spawnIngredient) { int times = lua_tonumber(L, 4); @@ -2765,6 +3059,27 @@ luaFunc(spawnParticleEffect) luaReturnPtr(pe); } +luaFunc(setNumSuckPositions) +{ + particleManager->setNumSuckPositions(lua_tointeger(L, 1)); + luaReturnNil(); +} + +luaFunc(setSuckPosition) +{ + particleManager->setSuckPosition(lua_tointeger(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3))); + luaReturnNil(); +} + +luaFunc(getSuckPosition) +{ + Vector *v = particleManager->getSuckPosition(lua_tointeger(L, 1)); + if(v) + luaReturnVec2(v->x, v->y); + luaReturnVec2(0.0f, 0.0f); +} + + luaFunc(bone_showFrame) { Bone *b = bone(L); @@ -2839,19 +3154,13 @@ luaFunc(bone_lookAtEntity) luaReturnNil(); } -luaFunc(bone_setSegs) +luaFunc(bone_lookAtPosition) { Bone *b = bone(L); if (b) - b->setSegs(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7), lua_tonumber(L, 8), lua_tointeger(L, 9)); - luaReturnNil(); -} - -luaFunc(entity_setSegs) -{ - Entity *e = entity(L); - if (e) - e->setSegs(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7), lua_tonumber(L, 8), lua_tointeger(L, 9)); + { + b->lookAt(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7)); + } luaReturnNil(); } @@ -2907,7 +3216,7 @@ luaFunc(entity_createEntity) Entity *e = entity(L); Entity *ret = NULL; if (e) - ret = dsq->game->createEntity(dsq->getEntityTypeIndexByName(getString(L, 2)), 0, e->position, 0, false, "", ET_ENEMY, 0, 0, true); + ret = dsq->game->createEntity(dsq->getEntityTypeIndexByName(getString(L, 2)), 0, e->position, 0, false, "", ET_ENEMY, true); luaReturnPtr(ret); } @@ -2922,6 +3231,11 @@ luaFunc(entity_checkSplash) luaReturnBool(ret); } +luaFunc(entity_isInCurrent) +{ + Entity *e = entity(L); + luaReturnBool(e ? e->isInCurrent() : false); +} luaFunc(entity_isUnderWater) { @@ -2977,6 +3291,18 @@ luaFunc(getLastCollidePosition) luaReturnVec2(dsq->game->lastCollidePosition.x, dsq->game->lastCollidePosition.y); } +luaFunc(getLastCollideTileType) +{ + luaReturnInt(dsq->game->lastCollideTileType); +} + +luaFunc(collideCircleWithGrid) +{ + bool c = dsq->game->collideCircleWithGrid(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)), lua_tonumber(L, 3)); + luaReturnBool(c); +} + + luaFunc(entity_isNearGround) { Entity *e = entity(L); @@ -3315,6 +3641,15 @@ luaFunc(entity_loadSkin) luaReturnNil(); } +luaFunc(entity_getSkeletalName) +{ + Entity *e = entity(L); + const char *s = ""; + if (e && e->skeletalSprite.isLoaded()) + s = e->skeletalSprite.filenameLoaded.c_str(); + luaReturnStr(s); +} + luaFunc(entity_idle) { Entity *e = entity(L); @@ -3351,6 +3686,21 @@ luaFunc(entity_setAnimLayerTimeMult) luaReturnNum(t); } +luaFunc(entity_getAnimLayerTimeMult) +{ + Entity *e = entity(L); + float t = 0; + if (e) + { + AnimationLayer *l = e->skeletalSprite.getAnimationLayer(lua_tointeger(L, 2)); + if (l) + { + t = l->timeMultiplier.x; + } + } + luaReturnNum(t); +} + luaFunc(entity_animate) { SkeletalSprite *skel = getSkeletalSprite(entity(L)); @@ -3379,6 +3729,19 @@ luaFunc(entity_stopAnimation) luaReturnNil(); } +luaFunc(entity_getAnimationLoop) +{ + int loop = 0; + SkeletalSprite *skel = getSkeletalSprite(entity(L)); + if (skel) + { + AnimationLayer *animlayer = skel->getAnimationLayer(lua_tointeger(L, 2)); + if (animlayer) + loop = animlayer->loop ? animlayer->loop : animlayer->enqueuedAnimationLoop; + } + luaReturnInt(loop); +} + // entity, x, y, time, ease, relative luaFunc(entity_move) { @@ -3447,6 +3810,16 @@ luaFunc(beam_setDamage) luaReturnNil(); } +luaFunc(beam_setDamageType) +{ + Beam *b = beam(L); + if (b) + { + b->damageData.damageType = (DamageType)lua_tointeger(L, 2); + } + luaReturnNil(); +} + luaFunc(beam_setBeamWidth) { Beam *b = beam(L); @@ -3476,6 +3849,19 @@ luaFunc(beam_setFirer) luaReturnNil(); } +// Note the additional trace() call +luaFunc(beam_setPosition_override) +{ + Beam *b = beam(L); + if (b) + { + b->position.interpolateTo(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), + lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7)); + b->trace(); + } + luaReturnNil(); +} + luaFunc(getStringBank) { luaReturnStr(dsq->continuity.stringBank.get(lua_tointeger(L, 1)).c_str()); @@ -3505,7 +3891,7 @@ luaFunc(createEntity) int y = lua_tointeger(L, 4); Entity *e = 0; - e = dsq->game->createEntity(type, 0, Vector(x, y), 0, false, name, ET_ENEMY, 0, 0, true); + e = dsq->game->createEntity(type, 0, Vector(x, y), 0, false, name, ET_ENEMY, true); luaReturnPtr(e); } @@ -3536,6 +3922,21 @@ luaFunc(unpause) luaReturnNil(); } +luaFunc(isPaused) +{ + luaReturnBool(dsq->game->isPaused()); +} + +luaFunc(isInGameMenu) +{ + luaReturnBool(dsq->game->isInGameMenu()); +} + +luaFunc(isInEditor) +{ + luaReturnBool(dsq->game->isSceneEditorActive()); +} + luaFunc(clearControlHint) { dsq->game->clearControlHint(); @@ -3548,6 +3949,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); @@ -3610,9 +4017,11 @@ luaFunc(entity_damage) { DamageData d; //d.attacker = e; - d.attacker = entity(L, 2); + d.attacker = lua_isuserdata(L, 2) ? entity(L, 2) : NULL; d.damage = lua_tonumber(L, 3); d.damageType = (DamageType)lua_tointeger(L, 4); + d.effectTime = lua_tonumber(L, 5); + d.useTimer = !getBool(L, 6); didDamage = e->damage(d); } luaReturnBool(didDamage); @@ -3630,13 +4039,24 @@ luaFunc(entity_setEntityLayer) luaReturnNil(); } +// Note that this overrides the generic obj_setRenderPass function for entities. +// (It's registered as "entity_setRenderPass" to Lua) +luaFunc(entity_setRenderPass_override) +{ + Entity *e = entity(L); + int pass = lua_tointeger(L, 2); + if (e) + e->setOverrideRenderPass(pass); + luaReturnNil(); +} + // intended to be used for setting max health and refilling it all luaFunc(entity_setHealth) { Entity *e = entity(L, 1); if (e) e->health = e->maxHealth = lua_tonumber(L, 2); - luaReturnNum(0); + luaReturnNil(); } luaFunc(entity_changeHealth) @@ -3644,7 +4064,7 @@ luaFunc(entity_changeHealth) Entity *e = entity(L, 1); if (e) e->health += lua_tonumber(L, 2); - luaReturnNum(0); + luaReturnNil(); } luaFunc(entity_heal) @@ -4140,9 +4560,16 @@ luaFunc(entity_collideHairVsCircle) int num = lua_tonumber(L, 3); // perc: percent of hairWidth to use as collide radius float perc = lua_tonumber(L, 4); - col = dsq->game->collideHairVsCircle(e, num, e2->position, e2->collideRadius, perc); + int colSegment; + col = dsq->game->collideHairVsCircle(e, num, e2->position, e2->collideRadius, perc, &colSegment); + if(col) + { + lua_pushboolean(L, true); + lua_pushinteger(L, colSegment); + return 2; + } } - luaReturnBool(col); + luaReturnBool(false); } luaFunc(entity_collideSkeletalVsCircleForListByName) @@ -4192,10 +4619,13 @@ luaFunc(entity_debugText) luaFunc(entity_getHealth) { Entity *e = entity(L); - if (e) - luaReturnNum(e->health); - else - luaReturnNum(0); + luaReturnNum(e ? e->health : 0); +} + +luaFunc(entity_getMaxHealth) +{ + Entity *e = entity(L); + luaReturnNum(e ? e->maxHealth : 0); } luaFunc(entity_initSegments) @@ -4276,7 +4706,12 @@ luaFunc(entity_updateSkeletal) { Entity *e = entity(L); if (e) + { + bool oldIgnore = e->skeletalSprite.ignoreUpdate; + e->skeletalSprite.ignoreUpdate = false; e->skeletalSprite.update(lua_tonumber(L, 2)); + e->skeletalSprite.ignoreUpdate = oldIgnore; + } luaReturnNil(); } @@ -4358,6 +4793,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); @@ -4512,6 +4959,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); @@ -4625,9 +5081,7 @@ luaFunc(entity_moveTowardsAngle) { Entity *e = entity(L); if (e) - { e->moveTowardsAngle(lua_tointeger(L, 2), lua_tonumber(L, 3), lua_tointeger(L, 4)); - } luaReturnNil(); } @@ -4635,9 +5089,7 @@ luaFunc(entity_moveAroundAngle) { Entity *e = entity(L); if (e) - { e->moveTowardsAngle(lua_tointeger(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4)); - } luaReturnNil(); } @@ -4645,9 +5097,7 @@ luaFunc(entity_moveTowards) { Entity *e = entity(L); if (e) - { e->moveTowards(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5)); - } luaReturnNil(); } @@ -4655,9 +5105,7 @@ luaFunc(entity_moveAround) { Entity *e = entity(L); if (e) - { e->moveAround(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6)); - } luaReturnNil(); } @@ -4665,12 +5113,43 @@ luaFunc(entity_addVel2) { Entity *e = entity(L); if (e) - { e->vel2 += Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)); + luaReturnNil(); +} + +luaFunc(entity_setVel2) +{ + Entity *e = entity(L); + if (e) + { + e->vel2 = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)); } luaReturnNil(); } +luaFunc(entity_getVel2Len) +{ + Entity *e = entity(L); + luaReturnNum(e ? e->vel2.getLength2D() : 0.0f); +} + +luaFunc(entity_setVel2Len) +{ + Entity *e = entity(L); + if(e) + e->vel2.setLength2D(lua_tonumber(L, 2)); + luaReturnNil(); +}; + +luaFunc(entity_getVel2) +{ + Entity *e = entity(L); + Vector vel2; + if(e) + vel2 = e->vel2; + luaReturnVec2(vel2.x, vel2.y); +} + luaFunc(entity_isValidTarget) { Entity *e = entity(L); @@ -4803,6 +5282,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) @@ -4975,6 +5460,12 @@ luaFunc(entity_setDeathScene) luaReturnNil(); } +luaFunc(entity_isDeathScene) +{ + Entity *e = entity(L); + luaReturnBool(e ? e->isDeathScene() : false); +} + luaFunc(entity_setCurrentTarget) { Entity *e = entity(L); @@ -5065,16 +5556,6 @@ luaFunc(warpNaijaToSceneNode) luaReturnNil(); } -luaFunc(registerSporeChildData) -{ - Entity *e = entity(L); - if (e) - { - dsq->continuity.registerSporeChildData(e); - } - luaReturnNil(); -} - luaFunc(entity_setDamageTarget) { Entity *e = entity(L); @@ -5156,9 +5637,18 @@ luaFunc(entity_getRandomTargetPoint) luaReturnNum(idx); } +luaFunc(entity_getNumTargetPoints) +{ + Entity *e = entity(L); + luaReturnInt(e ? e->getNumTargetPoints() : 0); +} + luaFunc(playVisualEffect) { - dsq->playVisualEffect(lua_tonumber(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3))); + Entity *target = NULL; + if(lua_isuserdata(L, 4)) + target = entity(L, 4); + dsq->playVisualEffect(lua_tonumber(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), target); luaReturnNil(); } @@ -5168,6 +5658,22 @@ luaFunc(playNoEffect) luaReturnNil(); } +luaFunc(createShockEffect) +{ + if (core->afterEffectManager) + { + core->afterEffectManager->addEffect(new ShockEffect( + Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)), // position + Vector(lua_tonumber(L, 3), lua_tonumber(L, 4)), // original position + lua_tonumber(L, 5), // amplitude + lua_tonumber(L, 6), // amplitude decay + lua_tonumber(L, 7), // frequency + lua_tonumber(L, 8), // wave length + lua_tonumber(L, 9))); // time multiplier + } + luaReturnNil(); +} + luaFunc(emote) { int emote = lua_tonumber(L, 1); @@ -5904,6 +6410,12 @@ luaFunc(entity_getDistanceToEntity) luaReturnNum(d); } +luaFunc(entity_isEntityInside) +{ + Entity *e = entity(L); + luaReturnBool(e ? e->isEntityInside() : false); +} + // entity_istargetInRange luaFunc(entity_isTargetInRange) { @@ -6036,36 +6548,10 @@ luaFunc(entity_partSetSegs) luaReturnNil(); } -luaFunc(getEntityInGroup) -{ - int gid = lua_tonumber(L, 1); - int iter = lua_tonumber(L, 2); - luaReturnPtr(dsq->game->getEntityInGroup(gid, iter)); -} - -luaFunc(entity_getGroupID) -{ - Entity *e = entity(L); - int id = 0; - if(e) - { - id = e->getGroupID(); - } - luaReturnNum(id); -} - luaFunc(entity_getID) { Entity *e = entity(L); - int id = 0; - if (e) - { - id = e->getID(); - std::ostringstream os; - os << "id: " << id; - debugLog(os.str()); - } - luaReturnNum(id); + luaReturnNum(e ? e->getID() : 0); } luaFunc(getEntityByID) @@ -6115,6 +6601,12 @@ luaFunc(node_setEffectOn) luaReturnNil(); } +luaFunc(node_isEffectOn) +{ + Path *p = path(L, 1); + luaReturnBool(p ? p->effectOn : false); +} + luaFunc(node_activate) { Path *p = path(L); @@ -6268,6 +6760,13 @@ luaFunc(ing_hasIET) luaReturnBool(has); } +luaFunc(ing_getIngredientName) +{ + Ingredient *i = getIng(L, 1); + IngredientData *data = i ? i->getIngredientData() : 0; + luaReturnStr(data ? data->name.c_str() : ""); +} + luaFunc(entity_getNearestEntity) { Entity *me = entity(L); @@ -6289,9 +6788,14 @@ luaFunc(entity_getNearestEntity) nameCheck = false; } - float range = lua_tointeger(L, 3); - int type = lua_tointeger(L, 4); - int damageTarget = lua_tointeger(L, 5); + float range = lua_tonumber(L, 3); + EntityType type = ET_NOTYPE; + if (lua_isnumber(L, 4)) + type = (EntityType)lua_tointeger(L, 4); + + DamageType damageTarget = DT_NONE; + if (lua_isnumber(L, 5)) + damageTarget = (DamageType)lua_tointeger(L, 5); Entity *closest = 0; Entity *ignore = 0; if (lua_isuserdata(L, 6)) @@ -6303,9 +6807,9 @@ luaFunc(entity_getNearestEntity) Entity *e = *i; if (e != me && e != ignore && e->isPresent() && e->isNormalLayer()) { - if (type == 0 || e->getEntityType() == type) + if (type == ET_NOTYPE || e->getEntityType() == type) { - if (damageTarget == 0 || e->isDamageTarget((DamageType)damageTarget)) + if (damageTarget == DT_NONE || e->isDamageTarget((DamageType)damageTarget)) { if (!name || ((nocasecmp(e->name, name)==0) == nameCheck)) { @@ -6323,6 +6827,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); @@ -6492,7 +7010,7 @@ luaFunc(entity_switchLayer) toLayer = dsq->getEntityLayerToLayer(lcode); if (e->getEntityType() == ET_AVATAR) - toLayer = LR_ENTITIES; + toLayer = LR_ENTITIES; core->switchRenderObjectLayer(e, toLayer); } @@ -6502,7 +7020,7 @@ luaFunc(entity_switchLayer) // entity numSegments segmentLength width texture luaFunc(entity_initHair) { - ScriptedEntity *se = scriptedEntity(L); + Entity *se = entity(L); if (se) { se->initHair(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), getString(L, 5)); @@ -6510,9 +7028,26 @@ luaFunc(entity_initHair) luaReturnNil(); } +luaFunc(entity_getHair) +{ + Entity *e = entity(L); + luaReturnPtr(e ? e->hair : NULL); +} + +luaFunc(entity_clearHair) +{ + Entity *e = entity(L); + if (e && e->hair) + { + e->hair->safeKill(); + e->hair = 0; + } + luaReturnNil(); +} + luaFunc(entity_getHairPosition) { - ScriptedEntity *se = scriptedEntity(L); + Entity *se = entity(L); float x=0; float y=0; int idx = lua_tonumber(L, 2); @@ -6531,7 +7066,7 @@ luaFunc(entity_getHairPosition) // entity x y z luaFunc(entity_setHairHeadPosition) { - ScriptedEntity *se = scriptedEntity(L); + Entity *se = entity(L); if (se) { se->setHairHeadPosition(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3))); @@ -6541,7 +7076,7 @@ luaFunc(entity_setHairHeadPosition) luaFunc(entity_updateHair) { - ScriptedEntity *se = scriptedEntity(L); + Entity *se = entity(L); if (se) { se->updateHair(lua_tonumber(L, 2)); @@ -6809,21 +7344,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(); } @@ -7081,6 +7616,20 @@ luaFunc(entity_setFlag) luaReturnNil(); } +luaFunc(entity_setPoison) +{ + Entity *e = entity(L); + if(e) + e->setPoison(lua_tonumber(L, 2), lua_tonumber(L, 3)); + luaReturnNil(); +} + +luaFunc(entity_getPoison) +{ + Entity *e = entity(L); + luaReturnNum(e ? e->getPoison() : 0.0f); +} + luaFunc(entity_getFlag) { Entity *e = entity(L); @@ -7194,6 +7743,82 @@ luaFunc(getScreenSize) luaReturnVec2(core->width, core->height); } +luaFunc(inv_isFull) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + bool full = false; + if(data) + full = dsq->continuity.isIngredientFull(data); + luaReturnBool(full); +} + +luaFunc(inv_getMaxAmount) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + luaReturnInt(data ? data->maxAmount : 0); +} + +luaFunc(inv_getAmount) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + luaReturnInt(data ? data->amount : 0); +} + +luaFunc(inv_add) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + if(data) + dsq->continuity.pickupIngredient(data, lua_tointeger(L, 2), false, false); + luaReturnNil(); +} + +luaFunc(inv_getGfx) +{ + luaReturnStr(dsq->continuity.getIngredientGfx(getString(L, 1)).c_str()); +} + +luaFunc(inv_remove) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + if(data && data->amount > 0) + { + data->amount--; + dsq->game->dropIngrNames.push_back(data->name); + dsq->continuity.removeEmptyIngredients(); + if(dsq->game->isInGameMenu()) + dsq->game->refreshFoodSlots(true); + } + luaReturnNil(); +} + +luaFunc(inv_getType) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + luaReturnInt(data ? data->type : 0); +} + +luaFunc(inv_getDisplayName) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + luaReturnStr(data ? data->displayName.c_str() : ""); +} + +luaFunc(inv_pickupEffect) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + if(data) + dsq->game->pickupIngredientEffects(data); + luaReturnNil(); +} + +luaFunc(learnRecipe) +{ + std::string name = getString(L, 1); + bool show = getBool(L, 2); + dsq->continuity.learnRecipe(name, show); + luaReturnNil(); +} + luaFunc(createDebugText) { DebugFont *txt = new DebugFont(lua_tointeger(L, 2), getString(L, 1)); @@ -7237,6 +7862,81 @@ luaFunc(text_setWidth) luaReturnNil(); } +luaFunc(loadShader) +{ + int handle = 0; + const char *vertRaw = getCString(L, 1); + const char *fragRaw = getCString(L, 2); + std::string vert, frag; + if(vertRaw) + findFile_helper(vertRaw, vert); + if(fragRaw) + findFile_helper(fragRaw, frag); + + if(core->afterEffectManager) + handle = core->afterEffectManager->loadShaderFile(vert.c_str(), frag.c_str()); + + luaReturnInt(handle); +} + +luaFunc(createShader) +{ + int handle = 0; + if(core->afterEffectManager) + handle = core->afterEffectManager->loadShaderSrc(getCString(L, 1), getCString(L, 2)); + luaReturnInt(handle); +} + +luaFunc(shader_setAsAfterEffect) +{ + int handle = lua_tointeger(L, 1); + int pos = lua_tointeger(L, 2); + bool done = false; + + if(core->afterEffectManager) + done = core->afterEffectManager->setShaderPipelinePos(handle, pos); + + luaReturnBool(done); +} + +luaFunc(shader_setNumAfterEffects) +{ + if(core->afterEffectManager) + core->afterEffectManager->setShaderPipelineSize(lua_tointeger(L, 1)); + luaReturnNil(); +} + +luaFunc(shader_setInt) +{ + if(core->afterEffectManager) + { + Shader *sh = core->afterEffectManager->getShaderPtr(lua_tointeger(L, 1)); + const char *name = getCString(L, 2); + if(sh && name) + sh->setInt(name, lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5), lua_tointeger(L, 6)); + } + luaReturnNil(); +} + +luaFunc(shader_setFloat) +{ + if(core->afterEffectManager) + { + Shader *sh = core->afterEffectManager->getShaderPtr(lua_tointeger(L, 1)); + const char *name = getCString(L, 2); + if(sh && name) + sh->setFloat(name, lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6)); + } + luaReturnNil(); +} + +luaFunc(shader_delete) +{ + if(core->afterEffectManager) + core->afterEffectManager->unloadShader(lua_tointeger(L, 1)); + luaReturnNil(); +} + //-------------------------------------------------------------------------------------------- @@ -7274,13 +7974,15 @@ static const struct { luaRegister(getNoteName), luaRegister(getWorldType), + luaRegister(setWorldType), + luaRegister(setWorldPaused), + luaRegister(isWorldPaused), luaRegister(getWaterLevel), luaRegister(setWaterLevel), - luaRegister(getEntityInGroup), - luaRegister(createQuad), + luaRegister(quad_setPauseLevel), luaRegister(setupEntity), luaRegister(setActivePet), @@ -7289,6 +7991,7 @@ static const struct { luaRegister(reconstructEntityGrid), luaRegister(ing_hasIET), + luaRegister(ing_getIngredientName), luaRegister(esetv), luaRegister(esetvf), @@ -7305,6 +8008,7 @@ static const struct { luaRegister(entity_setBoneLock), luaRegister(entity_setIngredient), luaRegister(entity_setDeathScene), + luaRegister(entity_isDeathScene), luaRegister(entity_setBeautyFlip), luaRegister(entity_setInvincible), @@ -7329,6 +8033,7 @@ static const struct { luaRegister(entity_setEatType), luaRegister(entity_setSpiritFreeze), + luaRegister(node_setSpiritFreeze), luaRegister(entity_setCanLeaveWater), @@ -7349,15 +8054,29 @@ 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), luaRegister(pause), luaRegister(unpause), + luaRegister(isPaused), + luaRegister(isInGameMenu), + luaRegister(isInEditor), luaRegister(vector_normalize), @@ -7381,15 +8100,15 @@ static const struct { luaRegister(entity_isUnderWater), luaRegister(entity_checkSplash), + luaRegister(entity_isInCurrent), luaRegister(entity_getRandomTargetPoint), luaRegister(entity_getTargetPoint), + luaRegister(entity_getNumTargetPoints), luaRegister(entity_setTargetRange), luaRegister(bone_addSegment), - luaRegister(entity_setSegs), - luaRegister(bone_setSegs), luaRegister(bone_setSegmentOffset), luaRegister(bone_setSegmentProps), @@ -7398,6 +8117,7 @@ static const struct { luaRegister(bone_showFrame), luaRegister(bone_lookAtEntity), + luaRegister(bone_lookAtPosition), luaRegister(entity_partSetSegs), @@ -7409,6 +8129,7 @@ static const struct { luaRegister(beam_setDamage), luaRegister(beam_setBeamWidth), luaRegister(beam_setFirer), + luaRegister(beam_setDamageType), luaRegister(getStringBank), @@ -7454,10 +8175,10 @@ static const struct { luaRegister(entity_getVectorToEntity), luaRegister(entity_getDistanceToTarget), + luaRegister(entity_getDistanceToPoint), luaRegister(entity_move), luaRegister(entity_getID), - luaRegister(entity_getGroupID), luaRegister(getEntityByID), @@ -7490,6 +8211,7 @@ static const struct { luaRegister(entity_partAlpha), luaRegister(entity_getHealth), + luaRegister(entity_getMaxHealth), luaRegister(entity_pushTarget), luaRegister(entity_msg), luaRegister(entity_updateMovement), @@ -7529,6 +8251,7 @@ static const struct { luaRegister(entity_warpSegments), luaRegister(entity_initSkeletal), luaRegister(entity_loadSkin), + luaRegister(entity_getSkeletalName), luaRegister(entity_initStrands), luaRegister(entity_hurtTarget), @@ -7550,6 +8273,7 @@ static const struct { luaRegister(entity_isTargetInRange), luaRegister(entity_getDistanceToEntity), + luaRegister(entity_isEntityInside), luaRegister(entity_isInvincible), @@ -7566,6 +8290,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), @@ -7574,7 +8299,9 @@ static const struct { luaRegister(entity_doCollisionAvoidance), luaRegister(entity_animate), luaRegister(entity_setAnimLayerTimeMult), + luaRegister(entity_getAnimLayerTimeMult), luaRegister(entity_stopAnimation), + luaRegister(entity_getAnimationLoop), luaRegister(entity_setCurrentTarget), luaRegister(entity_stopInterpolating), @@ -7585,11 +8312,8 @@ static const struct { luaRegister(entity_sound), luaRegister(entity_playSfx), - luaRegister(registerSporeChildData), luaRegister(registerSporeDrop), - luaRegister(getIngredientGfx), - luaRegister(spawnIngredient), luaRegister(spawnAllIngredients), luaRegister(spawnParticleEffect), @@ -7600,6 +8324,9 @@ static const struct { luaRegister(resetTimer), luaRegister(addInfluence), + luaRegister(setSuckPosition), + luaRegister(setSuckPosition), + luaRegister(setNumSuckPositions), luaRegister(setupBasicEntity), luaRegister(playMusic), luaRegister(playMusicStraight), @@ -7617,6 +8344,7 @@ static const struct { luaRegister(playVisualEffect), luaRegister(playNoEffect), + luaRegister(createShockEffect), luaRegister(setOverrideMusic), @@ -7729,7 +8457,7 @@ static const struct { luaRegister(hasFormUpgrade), - luaRegister(castSong), + luaRegister(singSong), luaRegister(isObstructed), luaRegister(isObstructedBlock), luaRegister(getObstruction), @@ -7754,10 +8482,17 @@ static const struct { luaRegister(avatar_isRolling), luaRegister(avatar_isOnWall), luaRegister(avatar_isShieldActive), + luaRegister(avatar_setShieldActive), luaRegister(avatar_getRollDirection), luaRegister(avatar_fallOffWall), luaRegister(avatar_setBlockSinging), + luaRegister(avatar_isBlockSinging), + + luaRegister(avatar_setSpeedMult), + luaRegister(avatar_setSpeedMult2), + luaRegister(avatar_getSpeedMult), + luaRegister(avatar_getSpeedMult2), luaRegister(avatar_toggleMovement), @@ -7832,8 +8567,21 @@ static const struct { luaRegister(createSpore), + luaRegister(getFirstShot), + luaRegister(getNextShot), luaRegister(shot_setAimVector), luaRegister(shot_setOut), + luaRegister(shot_getEffectTime), + luaRegister(shot_isIgnoreShield), + luaRegister(shot_setFirer), + luaRegister(shot_getFirer), + luaRegister(shot_setTarget), + luaRegister(shot_getTarget), + luaRegister(shot_setExtraDamage), + luaRegister(shot_getExtraDamage), + luaRegister(shot_getDamage), + luaRegister(shot_getDamageType), + luaRegister(shot_getName), luaRegister(entity_pathBurst), luaRegister(entity_handleShotCollisions), luaRegister(entity_handleShotCollisionsSkeletal), @@ -7851,14 +8599,6 @@ static const struct { luaRegister(entity_waitForPath), luaRegister(entity_watchForPath), - luaRegister(entity_addVel), - luaRegister(entity_addVel2), - luaRegister(entity_addRandomVel), - - luaRegister(entity_clearVel), - luaRegister(entity_clearVel2), - - luaRegister(entity_revive), luaRegister(entity_getTarget), @@ -7870,6 +8610,8 @@ static const struct { luaRegister(entity_initHair), luaRegister(entity_getHairPosition), + luaRegister(entity_getHair), + luaRegister(entity_clearHair), luaRegister(entity_setHairHeadPosition), luaRegister(entity_updateHair), @@ -7913,6 +8655,7 @@ static const struct { luaRegister(node_getAmount), luaRegister(node_getSize), luaRegister(node_setEffectOn), + luaRegister(node_isEffectOn), luaRegister(toggleSteam), luaRegister(toggleVersionLabel), @@ -7945,7 +8688,7 @@ static const struct { luaRegister(setSceneColor), - + luaRegister(getSceneColor), luaRegister(entity_watchEntity), @@ -7973,6 +8716,7 @@ static const struct { luaRegister(entity_setTexture), luaRegister(entity_setFillGrid), + luaRegister(entity_isFillGrid), luaRegister(entity_push), @@ -8016,6 +8760,13 @@ static const struct { luaRegister(entity_clearVel), luaRegister(entity_velTowards), + luaRegister(entity_setVel2), + luaRegister(entity_setVel2Len), + luaRegister(entity_getVel2Len), + luaRegister(entity_addVel2), + luaRegister(entity_getVel2), + luaRegister(entity_clearVel2), + luaRegister(updateMusic), @@ -8030,8 +8781,11 @@ static const struct { luaRegister(entity_getNearestEntity), luaRegister(entity_getNearestBoneToPosition), + luaRegister(getNearestEntity), luaRegister(entity_getNearestNode), + luaRegister(entity_setPoison), + luaRegister(entity_getPoison), luaRegister(node_getNearestEntity), luaRegister(node_getNearestNode), @@ -8051,16 +8805,37 @@ static const struct { luaRegister(getWallNormal), luaRegister(getLastCollidePosition), + luaRegister(getLastCollideTileType), + luaRegister(collideCircleWithGrid), luaRegister(getScreenVirtualOff), luaRegister(getScreenSize), + luaRegister(inv_isFull), + luaRegister(inv_getMaxAmount), + luaRegister(inv_getAmount), + luaRegister(inv_add), + luaRegister(inv_getGfx), + luaRegister(inv_remove), + luaRegister(inv_getType), + luaRegister(inv_getDisplayName), + luaRegister(inv_pickupEffect), + luaRegister(learnRecipe), + luaRegister(createDebugText), luaRegister(createBitmapText), luaRegister(text_setText), luaRegister(text_setFontSize), luaRegister(text_setWidth), + luaRegister(loadShader), + luaRegister(createShader), + luaRegister(shader_setAsAfterEffect), + luaRegister(shader_setNumAfterEffects), + luaRegister(shader_setFloat), + luaRegister(shader_setInt), + luaRegister(shader_delete), + luaRegister(isQuad), luaRegister(isNode), luaRegister(isObject), @@ -8082,11 +8857,15 @@ static const struct { // obj_* are not in the define above MAKE_ROBJ_FUNCS(_, obj) + // same for quad_* base functions + MAKE_QUAD_FUNCS(_, quad) // -- overrides / special cases-- {"bone_getPosition", l_bone_getWorldPosition}, { "entity_delete", l_entity_delete_override }, + { "entity_setRenderPass", l_entity_setRenderPass_override }, + { "beam_setPosition", l_beam_setPosition_override }, // -- deprecated/compatibility related functions below here -- @@ -8099,6 +8878,7 @@ static const struct { {"entity_rotateTo", l_entity_rotate}, {"entity_setColor", l_entity_color}, {"entity_setInternalOffset", l_entity_internalOffset}, + {"getIngredientGfx", l_inv_getGfx}, {"bone_setColor", l_bone_color}, @@ -8296,6 +9076,7 @@ static const struct { luaConstant(OBSCHECK_RANGE), luaConstant(OBSCHECK_4DIR), luaConstant(OBSCHECK_DOWN), + luaConstant(OBSCHECK_8DIR), luaConstant(EV_WALLOUT), luaConstant(EV_WALLTRANS), @@ -8319,6 +9100,7 @@ static const struct { luaConstant(EV_MINIMAP), luaConstant(EV_SOULSCREAMRADIUS), luaConstant(EV_WEBSLOW), + luaConstant(EV_NOAVOID), luaConstant(EV_MAX), {"EVT_NONE", 0}, @@ -8420,6 +9202,8 @@ static const struct { luaConstantFromClass(BLEND_DEFAULT, RenderObject), luaConstantFromClass(BLEND_ADD, RenderObject), {"BLEND_ADDITIVE", RenderObject::BLEND_ADD}, + luaConstantFromClass(BLEND_SUB, RenderObject), + luaConstantFromClass(BLEND_MULT, RenderObject), {"ENDING_NAIJACAVE", 10}, {"ENDING_NAIJACAVEDONE", 11}, @@ -8736,6 +9520,7 @@ static const struct { luaConstant(DT_CRUSH), luaConstant(DT_SPIKES), luaConstant(DT_STEAM), + luaConstant(DT_WALLHURT), luaConstant(FRAME_TIME), @@ -8755,6 +9540,18 @@ static const struct { luaConstant(ANIMLAYER_ARMOVERRIDE), luaConstant(ANIMLAYER_UPPERBODYIDLE), luaConstant(ANIMLAYER_HEADOVERRIDE), + + luaConstant(OT_EMPTY), + luaConstant(OT_BLACK), + luaConstant(OT_BLACKINVIS), + luaConstant(OT_INVISIBLE), + luaConstant(OT_INVISIBLEIN), + luaConstant(OT_HURT), + luaConstant(OT_INVISIBLEENT), + + luaConstant(SEE_MAP_NEVER), + luaConstant(SEE_MAP_DEFAULT), + luaConstant(SEE_MAP_ALWAYS), }; //============================================================================================ @@ -9308,6 +10105,41 @@ bool Script::call(const char *name, void *param1, void *param2, void *param3, fl return true; } +bool Script::call(const char *name, const char *param, bool *ret) +{ + lookupFunc(name); + lua_pushstring(L, param); + if (!doCall(1, 1)) + return false; + *ret = lua_toboolean(L, -1); + lua_pop(L, 1); + return true; +} + +bool Script::call(const char *name, const char *param, std::string *ret) +{ + lookupFunc(name); + lua_pushstring(L, param); + if (!doCall(1, 1)) + return false; + *ret = getString(L, -1); + lua_pop(L, 1); + return true; +} + +bool Script::call(const char *name, const char *param1, const char *param2, const char *param3, std::string *ret) +{ + lookupFunc(name); + lua_pushstring(L, param1); + lua_pushstring(L, param2); + lua_pushstring(L, param3); + if (!doCall(3, 1)) + return false; + *ret = getString(L, -1); + lua_pop(L, 1); + return true; +} + int Script::callVariadic(const char *name, lua_State *fromL, int nparams, void *param) { int oldtop = lua_gettop(L); diff --git a/Aquaria/ScriptInterface.h b/Aquaria/ScriptInterface.h index bf23dca..2815764 100644 --- a/Aquaria/ScriptInterface.h +++ b/Aquaria/ScriptInterface.h @@ -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); diff --git a/Aquaria/ScriptedEntity.cpp b/Aquaria/ScriptedEntity.cpp index 90e7e04..10f4c9e 100644 --- a/Aquaria/ScriptedEntity.cpp +++ b/Aquaria/ScriptedEntity.cpp @@ -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; diff --git a/Aquaria/ScriptedEntity.h b/Aquaria/ScriptedEntity.h index a838728..f943f6a 100644 --- a/Aquaria/ScriptedEntity.h +++ b/Aquaria/ScriptedEntity.h @@ -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 PartMap; @@ -69,12 +68,8 @@ public: typedef std::vector 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; diff --git a/Aquaria/Shot.cpp b/Aquaria/Shot.cpp index 9bde459..757b041 100644 --- a/Aquaria/Shot.cpp +++ b/Aquaria/Shot.cpp @@ -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::queueshotDeleteQueue; - 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; diff --git a/Aquaria/Shot.h b/Aquaria/Shot.h index c94d911..3864dd2 100644 --- a/Aquaria/Shot.h +++ b/Aquaria/Shot.h @@ -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 Shots; - static Shots shots; + typedef std::vector 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 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/StringBank.cpp b/Aquaria/StringBank.cpp index d1d144f..abdbb8d 100644 --- a/Aquaria/StringBank.cpp +++ b/Aquaria/StringBank.cpp @@ -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) diff --git a/Aquaria/UserSettings.cpp b/Aquaria/UserSettings.cpp index 49e19f4..32d47e9 100644 --- a/Aquaria/UserSettings.cpp +++ b/Aquaria/UserSettings.cpp @@ -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); diff --git a/Aquaria/UserSettings.h b/Aquaria/UserSettings.h index 1e31763..1c4607e 100644 --- a/Aquaria/UserSettings.h +++ b/Aquaria/UserSettings.h @@ -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; diff --git a/Aquaria/Web.cpp b/Aquaria/Web.cpp index 262df92..ae8c8e7 100644 --- a/Aquaria/Web.cpp +++ b/Aquaria/Web.cpp @@ -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); diff --git a/Aquaria/Web.h b/Aquaria/Web.h index 78762d0..8236ac8 100644 --- a/Aquaria/Web.h +++ b/Aquaria/Web.h @@ -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 Webs; 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..938d535 100644 --- a/BBGE/AfterEffect.cpp +++ b/BBGE/AfterEffect.cpp @@ -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; +} + diff --git a/BBGE/AfterEffect.h b/BBGE/AfterEffect.h index fd755d3..90c7d9f 100644 --- a/BBGE/AfterEffect.h +++ b/BBGE/AfterEffect.h @@ -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 shaderPipeline; // Shaders are applied in this order. Can contain the same pointer more than once. + std::vector loadedShaders; + FrameBuffer backupBuffer; - ActiveShader activeShader; }; 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..b996122 100644 --- a/BBGE/Base.cpp +++ b/BBGE/Base.cpp @@ -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 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) diff --git a/BBGE/Base.h b/BBGE/Base.h index 586a944..9c34277 100644 --- a/BBGE/Base.h +++ b/BBGE/Base.h @@ -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); 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 68d7c4f..f514807 100644 --- a/BBGE/Core.cpp +++ b/BBGE/Core.cpp @@ -41,6 +41,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #if BBGE_BUILD_WINDOWS #include +#include #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 diff --git a/BBGE/Core.h b/BBGE/Core.h index 2d62bda..e265dda 100644 --- a/BBGE/Core.h +++ b/BBGE/Core.h @@ -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; 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/ParticleManager.cpp b/BBGE/ParticleManager.cpp index bd19c51..030c064 100644 --- a/BBGE/ParticleManager.cpp +++ b/BBGE/ParticleManager.cpp @@ -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; } diff --git a/BBGE/Precacher.cpp b/BBGE/Precacher.cpp index 24e1585..3d604b8 100644 --- a/BBGE/Precacher.cpp +++ b/BBGE/Precacher.cpp @@ -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); diff --git a/BBGE/Precacher.h b/BBGE/Precacher.h index 87e9a05..4893123 100644 --- a/BBGE/Precacher.h +++ b/BBGE/Precacher.h @@ -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 renderObjects; private: bool cleaned; void (*loadProgressCallback)(); + std::string basedirOverride; }; #endif 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/Resource.h b/BBGE/Resource.h index 6de0875..5ea7f6d 100644 --- a/BBGE/Resource.h +++ b/BBGE/Resource.h @@ -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; 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..c6468bc 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,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 +} diff --git a/BBGE/Shader.h b/BBGE/Shader.h index 1eb4cd9..2b978e7 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 { 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/BBGE/SkeletalSprite.cpp b/BBGE/SkeletalSprite.cpp index 63a0976..ea0a5d3 100644 --- a/BBGE/SkeletalSprite.cpp +++ b/BBGE/SkeletalSprite.cpp @@ -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; } diff --git a/BBGE/SkeletalSprite.h b/BBGE/SkeletalSprite.h index 518f687..b170765 100644 --- a/BBGE/SkeletalSprite.h +++ b/BBGE/SkeletalSprite.h @@ -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 animations; std::vector bones; diff --git a/BBGE/StateManager.cpp b/BBGE/StateManager.cpp index e82aefb..f0a81ad 100644 --- a/BBGE/StateManager.cpp +++ b/BBGE/StateManager.cpp @@ -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]) diff --git a/BBGE/Texture.cpp b/BBGE/Texture.cpp index a15e69c..97cd22b 100644 --- a/BBGE/Texture.cpp +++ b/BBGE/Texture.cpp @@ -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); } diff --git a/BBGE/Vector.cpp b/BBGE/Vector.cpp index 94eeb49..73b24bc 100644 --- a/BBGE/Vector.cpp +++ b/BBGE/Vector.cpp @@ -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) { diff --git a/BBGE/Vector.h b/BBGE/Vector.h index 9cb705b..e56fbac 100644 --- a/BBGE/Vector.h +++ b/BBGE/Vector.h @@ -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; } diff --git a/CMakeLists.txt b/CMakeLists.txt index 204c987..665ae5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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") 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/ExternalLibs/glfont2/glfont2.cpp b/ExternalLibs/glfont2/glfont2.cpp index 7cff0ff..bb8e9ca 100644 --- a/ExternalLibs/glfont2/glfont2.cpp +++ b/ExternalLibs/glfont2/glfont2.cpp @@ -11,15 +11,15 @@ #include "ByteBuffer.h" using namespace std; -//OpenGL headers -/* -#ifdef _WINDOWS -#include -#endif -#include -*/ -#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 +#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; } diff --git a/ExternalLibs/ttvfs/VFSDefines.h b/ExternalLibs/ttvfs/VFSDefines.h index 4439bda..7cd8642 100644 --- a/ExternalLibs/ttvfs/VFSDefines.h +++ b/ExternalLibs/ttvfs/VFSDefines.h @@ -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. diff --git a/ExternalLibs/ttvfs/VFSDir.cpp b/ExternalLibs/ttvfs/VFSDir.cpp index 940b87d..536ab72 100644 --- a/ExternalLibs/ttvfs/VFSDir.cpp +++ b/ExternalLibs/ttvfs/VFSDir.cpp @@ -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::iterator it = li.begin(); it != li.end(); ++it) { // subdir was already present, move over and erase diff --git a/ExternalLibs/ttvfs/VFSTools.cpp b/ExternalLibs/ttvfs/VFSTools.cpp index 6a34e28..f3d04ca 100644 --- a/ExternalLibs/ttvfs/VFSTools.cpp +++ b/ExternalLibs/ttvfs/VFSTools.cpp @@ -18,9 +18,9 @@ # include #else # ifdef __HAIKU__ -# include +# include # else -# include +# include # endif # include #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 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::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::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 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::iterator it = li.begin(); it != li.end(); ++it) - files.push_back(dir + *it); - - li.clear(); - GetDirList(dir.c_str(), li, true); - for(std::deque::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::iterator it = li.begin(); it != li.end(); ++it) - files.push_back(dir + *it); - - li.clear(); - GetDirList(dir.c_str(), li, true); - for(std::deque::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; } diff --git a/ExternalLibs/ttvfs/VFSTools.h b/ExternalLibs/ttvfs/VFSTools.h index 36d3832..34b6f64 100644 --- a/ExternalLibs/ttvfs/VFSTools.h +++ b/ExternalLibs/ttvfs/VFSTools.h @@ -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 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); diff --git a/ExternalLibs/ttvfs_zip/VFSFileZip.cpp b/ExternalLibs/ttvfs_zip/VFSFileZip.cpp index 9bacaf9..2f4ecb3 100644 --- a/ExternalLibs/ttvfs_zip/VFSFileZip.cpp +++ b/ExternalLibs/ttvfs_zip/VFSFileZip.cpp @@ -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? { diff --git a/README.txt b/README.txt index 1fe8854..299db66 100644 --- a/README.txt +++ b/README.txt @@ -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. diff --git a/files/data/worldmap.txt b/files/data/worldmap.txt new file mode 100644 index 0000000..f82cc39 --- /dev/null +++ b/files/data/worldmap.txt @@ -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 diff --git a/files/gfx/gui/worldmap/whale.png b/files/gfx/gui/worldmap/whale.png new file mode 100644 index 0000000..016b8d1 Binary files /dev/null and b/files/gfx/gui/worldmap/whale.png differ diff --git a/game_scripts/scripts/.gitignore b/game_scripts/scripts/.gitignore new file mode 100644 index 0000000..fa9ed09 --- /dev/null +++ b/game_scripts/scripts/.gitignore @@ -0,0 +1,2 @@ +vox/* +entities/*.txt 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/energygodspirit.lua b/game_scripts/scripts/entities/energygodspirit.lua index bcb303c..4611eba 100644 --- a/game_scripts/scripts/entities/energygodspirit.lua +++ b/game_scripts/scripts/entities/energygodspirit.lua @@ -32,7 +32,7 @@ v.attackDelay = 0 v.noteQuad = 0 - +v.holdingNote = false v.maxHits = 6 v.hits = v.maxHits diff --git a/game_scripts/scripts/entities/finalspiritcommon.lua b/game_scripts/scripts/entities/finalspiritcommon.lua index 92a7582..cad965d 100644 --- a/game_scripts/scripts/entities/finalspiritcommon.lua +++ b/game_scripts/scripts/entities/finalspiritcommon.lua @@ -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) diff --git a/game_scripts/scripts/entities/pet_piranha.lua b/game_scripts/scripts/entities/pet_piranha.lua index 0bf82f7..fb8ec02 100644 --- a/game_scripts/scripts/entities/pet_piranha.lua +++ b/game_scripts/scripts/entities/pet_piranha.lua @@ -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 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 6705212..ef5d40e 100644 --- a/win/vc90/BBGE.vcproj +++ b/win/vc90/BBGE.vcproj @@ -200,14 +200,6 @@ RelativePath="..\..\BBGE\AfterEffect.h" > - - - - @@ -316,14 +308,6 @@ RelativePath="..\..\BBGE\Gradient.h" > - - - - @@ -368,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}" > + +