diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index 1abb763..c597fd4 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -4911,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) diff --git a/Aquaria/Continuity.cpp b/Aquaria/Continuity.cpp index 18ee693..3a1ed8c 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; } } @@ -607,8 +608,10 @@ std::string Continuity::getAllIEString(IngredientData *data) return os.str(); } -void Continuity::applyIngredientEffects(IngredientData *data) +// returns true if eaten +bool Continuity::applyIngredientEffects(IngredientData *data) { + bool eaten = true; float y =0; for (int i = 0; i < data->effects.size(); i++) { @@ -841,28 +844,37 @@ void Continuity::applyIngredientEffects(IngredientData *data) // this item should only affect li if naija drops it and li eats it. } break; + case IET_SCRIPT: + { + // If this fails, it will still be eaten + if(dsq->game->cookingScript) + dsq->game->cookingScript->call("useIngredient", data->name.c_str(), &eaten); + } + break; default: { char str[256]; sprintf((char*)&str, "ingredient effect not defined, index[%d]", int(useType)); errorLog(str); + eaten = false; } break; } } + return eaten; } std::string Continuity::getIngredientAffectsString(IngredientData *data) { - - /* - std::string str; - for (int i = 0; i < data->effects.size(); i++) + if(data->type == IET_SCRIPT) { - str += splitCamelCase(getIngredientDescription(data->effects[i].type)) + "\n"; + if(dsq->game->cookingScript) + { + std::string ret = ""; + dsq->game->cookingScript->call("getIngredientString", data->name.c_str(), &ret); + return ret; + } } - return str; - */ return getAllIEString(data); } @@ -910,6 +922,43 @@ void Continuity::clearIngredientData() ingredientData.clear(); } +void Continuity::loadIngredientData() +{ + if(ingredients.size()) + { + debugLog("Can't reload ingredient data, inventory is not empty"); + return; // ... because otherwise there would be dangling pointers and it would crash. + } + + clearIngredientData(); + ingredientDescriptions.clear(); + ingredientDisplayNames.clear(); + recipes.clear(); + + loadIngredientDisplayNames("data/ingredientnames.txt"); + + std::string fname = localisePath("data/ingredientnames.txt"); + loadIngredientDisplayNames(fname); + + if(dsq->mod.isActive()) + { + fname = localisePath(dsq->mod.getPath() + "ingredientnames.txt", dsq->mod.getPath()); + loadIngredientDisplayNames(fname); + } + + if(dsq->mod.isActive()) + { + //load mod ingredients + loadIngredientData(dsq->mod.getPath() + "ingredients.txt"); + } + + //load ingredients for the main game + if(ingredientData.empty() && recipes.empty()) + { + loadIngredientData("data/ingredients.txt"); + } +} + void Continuity::loadIngredientData(const std::string &file) { std::string line, name, gfx, type, effects; @@ -920,6 +969,7 @@ void Continuity::loadIngredientData(const std::string &file) InStream in(file.c_str()); bool recipes = false; + bool extradata = false; while (std::getline(in, line)) { std::istringstream inLine(line); @@ -931,6 +981,11 @@ void Continuity::loadIngredientData(const std::string &file) recipes = true; break; } + else if(name == "==Extra==") + { + extradata = true; + break; + } inLine >> gfx >> type; std::getline(inLine, effects); @@ -1032,6 +1087,10 @@ void Continuity::loadIngredientData(const std::string &file) { fx.type = IET_LI; } + else if (bit.find("script") != std::string::npos) + { + fx.type = IET_SCRIPT; + } int c = 0; while (c < bit.size()) @@ -1052,6 +1111,31 @@ void Continuity::loadIngredientData(const std::string &file) ingredientData.push_back(data); } + if(extradata) + { + while (std::getline(in, line)) + { + SimpleIStringStream inLine(line.c_str(), SimpleIStringStream::REUSE); + int maxAmount = MAX_INGREDIENT_AMOUNT; + int rotKind = 1; + inLine >> name >> maxAmount >> rotKind; + if (name == "==Recipes==") + { + recipes = true; + break; + } + IngredientData *data = getIngredientDataByName(name); + if(!data) + { + errorLog("Specifying data for undefined ingredient: " + name); + continue; + } + + data->maxAmount = maxAmount; + data->rotKind = rotKind; + } + } + if (recipes) { bool quitNext = false; @@ -2310,15 +2394,34 @@ void Continuity::saveFile(int slot, Vector position, unsigned char *scrShotData, if (hasUserString) os << spacesToUnderscores((*i).userString) << " "; - - /* - std::ostringstream os2; - os2 << "Saving a Gem called [" << (*i).name << "] with userString [" << (*i).userString << "] pos (" << (*i).pos.x << ", " << (*i).pos.y << ")\n"; - os2 << os.str() << "\n"; - debugLog(os2.str()); - */ } gems.SetAttribute("c", os.str()); + + // This is the format used in the android version. Keeping this commented out for now, + // but it should be used instead of the code above in some time -- FG + /* + os.str(""); + bool hasMapName = false; + os << this->gems.size() << " "; + for (Gems::iterator i = this->gems.begin(); i != this->gems.end(); i++) + { + os << (*i).name << " "; + hasMapName = !(*i).mapName.empty(); + os << hasMapName << " "; + if(hasMapName) + os << (*i).mapName << " "; // warning: this will fail to load if the map name contains whitespace + + os << (*i).pos.x << " " << (*i).pos.y << " "; + os << (*i).canMove << " "; + + hasUserString = !(*i).userString.empty(); + os << hasUserString << " "; + if (hasUserString) + os << spacesToUnderscores((*i).userString) << " "; + } + gems.SetAttribute("d", os.str()); + */ + } doc.InsertEndChild(gems); @@ -2415,6 +2518,7 @@ void Continuity::saveFile(int slot, Vector position, unsigned char *scrShotData, startData.SetAttribute("scene", dsq->game->sceneName); startData.SetAttribute("exp", dsq->continuity.exp); startData.SetAttribute("h", dsq->continuity.maxHealth); + // ANDROID TODO: "ch" field startData.SetAttribute("naijaModel", dsq->continuity.naijaModel); startData.SetAttribute("costume", dsq->continuity.costume); startData.SetAttribute("form", dsq->continuity.form); @@ -2433,6 +2537,16 @@ void Continuity::saveFile(int slot, Vector position, unsigned char *scrShotData, } startData.SetAttribute("songs", os2.str()); + // new format as used by android version + std::ostringstream ingrNames; + for (int i = 0; i < ingredients.size(); i++) + { + IngredientData *data = ingredients[i]; + ingrNames << data->name << " " << data->amount << " "; + } + startData.SetAttribute("ingrNames", ingrNames.str()); + + // for compatibility with older versions std::ostringstream ingrOs; for (int i = 0; i < ingredients.size(); i++) { @@ -2505,6 +2619,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; @@ -2688,6 +2805,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"); @@ -2725,6 +2843,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()); @@ -2764,7 +2930,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; } @@ -2807,6 +2975,23 @@ void Continuity::loadFile(int slot) dsq->continuity.form = FormType(atoi(startData->Attribute("form"))); } + 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); + } + } + } + if (startData->Attribute("ingr")) { std::istringstream is(startData->Attribute("ingr")); @@ -2870,6 +3055,8 @@ void Continuity::loadFile(int slot) } } + // TODO ANDROID: "ch" field + if (startData->Attribute("h")) { int read = atoi(startData->Attribute("h")); @@ -3053,6 +3240,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 @@ -3163,6 +3351,7 @@ void Continuity::reset() //worldMapTiles.clear(); speedMult = biteMult = fishPoison = defenseMult = 1; + speedMult2 = 1; poison = 0; energyMult = 0; light = petPower = 0; @@ -3192,40 +3381,11 @@ void Continuity::reset() worldMap.load(); - ingredients.clear(); naijaEats.clear(); - foodSortType = 0; + ingredients.clear(); - //load ingredients - - ingredientDisplayNames.clear(); - - loadIngredientDisplayNames("data/ingredientnames.txt"); - - std::string fname = localisePath("data/ingredientnames.txt"); - loadIngredientDisplayNames(fname); - - if(dsq->mod.isActive()) - { - fname = localisePath(dsq->mod.getPath() + "ingredientnames.txt", dsq->mod.getPath()); - loadIngredientDisplayNames(fname); - } - - ingredientDescriptions.clear(); - ingredientData.clear(); - recipes.clear(); - - if(dsq->mod.isActive()) - { - //load mod ingredients - loadIngredientData(dsq->mod.getPath() + "ingredients.txt"); - } - - //load ingredients for the main game - if(ingredientData.empty() && recipes.empty()) { - loadIngredientData("data/ingredients.txt"); - } + loadIngredientData(); // must be after clearing ingredients loadPetData(); diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index dca1cc4..cfa6aca 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -614,6 +614,7 @@ void DSQ::debugMenu() core->afterEffectManager->loadShaders(); } dsq->user.load(); + dsq->continuity.loadIngredientData(); } else if (c == '2') { @@ -2154,7 +2155,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); diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 3be5ae6..b4a6461 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -618,6 +618,7 @@ struct GemData GemData() { canMove=false; } std::string name; std::string userString; + std::string mapName; bool canMove; Vector pos; }; @@ -685,6 +686,7 @@ enum IngredientEffectType IET_POISON = 17, IET_BLIND = 18, IET_ALLSTATUS = 19, + IET_SCRIPT = 20, IET_MAX }; @@ -715,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; @@ -1051,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 @@ -1059,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(); } @@ -1099,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(); diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 5f2de4e..3270fbc 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 @@ -1236,6 +1234,8 @@ Game::Game() : StateObject() lastCollideMaskIndex = -1; worldPaused = false; + cookingScript = 0; + } Game::~Game() @@ -5836,41 +5836,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++) @@ -5994,7 +5959,6 @@ void Game::action(int id, int state) if (foodSlots[i]->isCursorIn() && foodSlots[i]->getIngredient()) { foodSlots[i]->moveRight(); - adjustFoodSlotCursor(); break; } } @@ -6031,7 +5995,6 @@ void Game::action(int id, int state) if (ingrIndex >= 0) { foodSlots[ingrIndex]->discard(); - adjustFoodSlotCursor(); } } } @@ -6709,6 +6672,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 /* @@ -7244,7 +7215,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"); @@ -7424,6 +7410,8 @@ void Game::onCook() } refreshFoodSlots(true); +endcook: + AquariaGuiElement::canDirMoveGlobal = true; isCooking = false; @@ -8740,7 +8728,6 @@ void Game::refreshFoodSlots(bool effects) { foodSlots[i]->refresh(effects); } - adjustFoodSlotCursor(); } void Game::refreshTreasureSlots() diff --git a/Aquaria/Game.h b/Aquaria/Game.h index d9c103e..3585cca 100644 --- a/Aquaria/Game.h +++ b/Aquaria/Game.h @@ -714,6 +714,8 @@ public: Ingredient *getNearestIngredient(const Vector &pos, int radius); Entity *getNearestEntity(const Vector &pos, int radius, Entity *ignore = 0, EntityType et=ET_NOTYPE, DamageType dt=DT_NONE, int lrStart=-1, int lrEnd=-1); + Script *cookingScript; + void spawnManaBall(Vector pos, float a); bool updateMusic(); std::string overrideMusic; diff --git a/Aquaria/Ingredient.cpp b/Aquaria/Ingredient.cpp index 97b9e42..f5b759d 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() diff --git a/Aquaria/SceneEditor.cpp b/Aquaria/SceneEditor.cpp index ae8dc7a..cf173fb 100644 --- a/Aquaria/SceneEditor.cpp +++ b/Aquaria/SceneEditor.cpp @@ -3578,10 +3578,10 @@ void SceneEditor::update(float dt) (dsq->getGameCursorPosition().y - cursorOffset.y)*factor); //editingElement->scale=oldScale + add; Vector sz = oldScale + add; - if (sz.x < 64) - sz.x = 64; - if (sz.y < 64) - sz.y = 64; + if (sz.x < 32) + sz.x = 32; + if (sz.y < 32) + sz.y = 32; editingPath->rect.x1 = -sz.x/2; editingPath->rect.x2 = sz.x/2; editingPath->rect.y1 = -sz.y/2; diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 3c2b116..856f1fb 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -76,6 +76,7 @@ static const char * const interfaceFunctions[] = { "activate", "animationKey", "castSong", + "cookFailure", "damage", "deathNotify", "dieEaten", @@ -84,6 +85,7 @@ static const char * const interfaceFunctions[] = { "entityDied", "exitState", "exitTimer", + "getIngredientString", "hitEntity", "hitSurface", "init", @@ -98,6 +100,7 @@ static const char * const interfaceFunctions[] = { "songNoteDone", "sporesDropped", "update", + "useIngredient", "useTreasure", NULL }; @@ -2895,6 +2898,28 @@ luaFunc(avatar_getSpellCharge) luaReturnNum(dsq->game->avatar->state.spellCharge); } +luaFunc(avatar_setSpeedMult) +{ + dsq->continuity.setSpeedMultiplier(lua_tonumber(L, 1), lua_tonumber(L, 2)); + luaReturnNil(); +} + +luaFunc(avatar_setSpeedMult2) +{ + dsq->continuity.speedMult2 = lua_tonumber(L, 1); + luaReturnNil(); +} + +luaFunc(avatar_getSpeedMult) +{ + luaReturnNum(dsq->continuity.speedMult); +} + +luaFunc(avatar_getSpeedMult2) +{ + luaReturnNum(dsq->continuity.speedMult2); +} + luaFunc(jumpState) { dsq->enqueueJumpState(getString(L, 1), getBool(L, 2)); @@ -2997,11 +3022,6 @@ luaFunc(entity_followPath) luaReturnNil(); } -luaFunc(getIngredientGfx) -{ - luaReturnStr(dsq->continuity.getIngredientGfx(getString(L, 1)).c_str()); -} - luaFunc(spawnIngredient) { int times = lua_tonumber(L, 4); @@ -3210,6 +3230,11 @@ luaFunc(entity_checkSplash) luaReturnBool(ret); } +luaFunc(entity_isInCurrent) +{ + Entity *e = entity(L); + luaReturnBool(e ? e->isInCurrent() : false); +} luaFunc(entity_isUnderWater) { @@ -5611,6 +5636,12 @@ luaFunc(entity_getRandomTargetPoint) luaReturnNum(idx); } +luaFunc(entity_getNumTargetPoints) +{ + Entity *e = entity(L); + luaReturnInt(e ? e->getNumTargetPoints() : 0); +} + luaFunc(playVisualEffect) { Entity *target = NULL; @@ -6728,6 +6759,13 @@ luaFunc(ing_hasIET) luaReturnBool(has); } +luaFunc(ing_getIngredientName) +{ + Ingredient *i = getIng(L, 1); + IngredientData *data = i ? i->getIngredientData() : 0; + luaReturnStr(data ? data->name.c_str() : ""); +} + luaFunc(entity_getNearestEntity) { Entity *me = entity(L); @@ -7704,6 +7742,82 @@ luaFunc(getScreenSize) luaReturnVec2(core->width, core->height); } +luaFunc(inv_isFull) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + bool full = false; + if(data) + full = dsq->continuity.isIngredientFull(data); + luaReturnBool(full); +} + +luaFunc(inv_getMaxAmount) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + luaReturnInt(data ? data->maxAmount : 0); +} + +luaFunc(inv_getAmount) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + luaReturnInt(data ? data->amount : 0); +} + +luaFunc(inv_add) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + if(data) + dsq->continuity.pickupIngredient(data, lua_tointeger(L, 2), false, false); + luaReturnNil(); +} + +luaFunc(inv_getGfx) +{ + luaReturnStr(dsq->continuity.getIngredientGfx(getString(L, 1)).c_str()); +} + +luaFunc(inv_remove) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + if(data && data->amount > 0) + { + data->amount--; + dsq->game->dropIngrNames.push_back(data->name); + dsq->continuity.removeEmptyIngredients(); + if(dsq->game->isInGameMenu()) + dsq->game->refreshFoodSlots(true); + } + luaReturnNil(); +} + +luaFunc(inv_getType) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + luaReturnInt(data ? data->type : 0); +} + +luaFunc(inv_getDisplayName) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + luaReturnStr(data ? data->displayName.c_str() : ""); +} + +luaFunc(inv_pickupEffect) +{ + IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1)); + if(data) + dsq->game->pickupIngredientEffects(data); + luaReturnNil(); +} + +luaFunc(learnRecipe) +{ + std::string name = getString(L, 1); + bool show = getBool(L, 2); + dsq->continuity.learnRecipe(name, show); + luaReturnNil(); +} + luaFunc(createDebugText) { DebugFont *txt = new DebugFont(lua_tointeger(L, 2), getString(L, 1)); @@ -7876,6 +7990,7 @@ static const struct { luaRegister(reconstructEntityGrid), luaRegister(ing_hasIET), + luaRegister(ing_getIngredientName), luaRegister(esetv), luaRegister(esetvf), @@ -7984,9 +8099,11 @@ static const struct { luaRegister(entity_isUnderWater), luaRegister(entity_checkSplash), + luaRegister(entity_isInCurrent), luaRegister(entity_getRandomTargetPoint), luaRegister(entity_getTargetPoint), + luaRegister(entity_getNumTargetPoints), luaRegister(entity_setTargetRange), @@ -8196,8 +8313,6 @@ static const struct { luaRegister(registerSporeDrop), - luaRegister(getIngredientGfx), - luaRegister(spawnIngredient), luaRegister(spawnAllIngredients), luaRegister(spawnParticleEffect), @@ -8373,6 +8488,11 @@ static const struct { luaRegister(avatar_setBlockSinging), luaRegister(avatar_isBlockSinging), + luaRegister(avatar_setSpeedMult), + luaRegister(avatar_setSpeedMult2), + luaRegister(avatar_getSpeedMult), + luaRegister(avatar_getSpeedMult2), + luaRegister(avatar_toggleMovement), @@ -8690,6 +8810,17 @@ static const struct { luaRegister(getScreenVirtualOff), luaRegister(getScreenSize), + luaRegister(inv_isFull), + luaRegister(inv_getMaxAmount), + luaRegister(inv_getAmount), + luaRegister(inv_add), + luaRegister(inv_getGfx), + luaRegister(inv_remove), + luaRegister(inv_getType), + luaRegister(inv_getDisplayName), + luaRegister(inv_pickupEffect), + luaRegister(learnRecipe), + luaRegister(createDebugText), luaRegister(createBitmapText), luaRegister(text_setText), @@ -8746,6 +8877,7 @@ static const struct { {"entity_rotateTo", l_entity_rotate}, {"entity_setColor", l_entity_color}, {"entity_setInternalOffset", l_entity_internalOffset}, + {"getIngredientGfx", l_inv_getGfx}, {"bone_setColor", l_bone_color}, @@ -9972,6 +10104,41 @@ bool Script::call(const char *name, void *param1, void *param2, void *param3, fl return true; } +bool Script::call(const char *name, const char *param, bool *ret) +{ + lookupFunc(name); + lua_pushstring(L, param); + if (!doCall(1, 1)) + return false; + *ret = lua_toboolean(L, -1); + lua_pop(L, 1); + return true; +} + +bool Script::call(const char *name, const char *param, std::string *ret) +{ + lookupFunc(name); + lua_pushstring(L, param); + if (!doCall(1, 1)) + return false; + *ret = getString(L, -1); + lua_pop(L, 1); + return true; +} + +bool Script::call(const char *name, const char *param1, const char *param2, const char *param3, std::string *ret) +{ + lookupFunc(name); + lua_pushstring(L, param1); + lua_pushstring(L, param2); + lua_pushstring(L, param3); + if (!doCall(3, 1)) + return false; + *ret = getString(L, -1); + lua_pop(L, 1); + return true; +} + int Script::callVariadic(const char *name, lua_State *fromL, int nparams, void *param) { int oldtop = lua_gettop(L); 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/files/data/worldmap.txt b/files/data/worldmap.txt new file mode 100644 index 0000000..089a59e --- /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 19 UNKNOWN 0 1 0 0 0 1 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