From 84a73b59f99f15b0ab009f7606f190f4394963ad Mon Sep 17 00:00:00 2001 From: fgenesis Date: Wed, 19 Jun 2013 02:26:12 +0200 Subject: [PATCH 1/9] Hopefully fixed piranha pet script warning (thx `Nax for reporting) --- game_scripts/scripts/entities/pet_piranha.lua | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) 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 From 61395779a1fbc4d94d889b088d36f648d2e83c91 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Wed, 19 Jun 2013 15:09:05 +0200 Subject: [PATCH 2/9] Do not try to load .zip files in _mods automatically. This has been a great source of confusion and it's better to remove it. --- Aquaria/DSQ.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index dca1cc4..31f1b97 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -2154,7 +2154,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); From 1bbd9e097dd0ba94fbc72f173f3e16ac71284d06 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Thu, 20 Jun 2013 04:49:20 +0200 Subject: [PATCH 3/9] Initial supported for scripted ingredients, not fully tested. This adds a few additional interface functions, to be defined in: scripts/global/cooking.lua, or _mods/XYZ/scripts/cooking.lua Added functions: cookFailure(a,b,c) - Called when no recipe could be found for ingredients a,b,c getIngredientString() - Called by the menu. Expected to return effects description for scripted ingredient.. useIngredient(name) - Called when a scripted ingredient will be eaten. Return true to eat. Use a line like this in ingredients.txt: LuaLoaf sealoaf Loaf (script) to enable calling useIngredient() upon eating. --- Aquaria/Continuity.cpp | 74 +++++++++++++++---- Aquaria/DSQ.h | 7 +- Aquaria/Game.cpp | 87 +++++++++------------- Aquaria/Game.h | 2 + Aquaria/Ingredient.cpp | 13 +--- Aquaria/SceneEditor.cpp | 8 +- Aquaria/ScriptInterface.cpp | 141 ++++++++++++++++++++++++++++++++++-- Aquaria/ScriptInterface.h | 6 ++ 8 files changed, 250 insertions(+), 88 deletions(-) diff --git a/Aquaria/Continuity.cpp b/Aquaria/Continuity.cpp index 18ee693..1a39f32 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,36 @@ 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); + } 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); } @@ -920,6 +931,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 +943,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); @@ -944,7 +961,7 @@ void Continuity::loadIngredientData(const std::string &file) if (p1 != std::string::npos && p2 != std::string::npos) { effects = effects.substr(p1+1, p2-(p1+1)); - std::istringstream fxLine(effects); + SimpleIStringStream fxLine(effects.c_str(), SimpleIStringStream::REUSE); std::string bit; while (fxLine >> bit) { @@ -1032,6 +1049,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 +1073,31 @@ void Continuity::loadIngredientData(const std::string &file) ingredientData.push_back(data); } + if(extradata) + { + while (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; + continue; + } + 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; diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 3be5ae6..b4df465 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -685,6 +685,7 @@ enum IngredientEffectType IET_POISON = 17, IET_BLIND = 18, IET_ALLSTATUS = 19, + IET_SCRIPT = 20, IET_MAX }; @@ -715,9 +716,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 +1054,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,7 +1062,7 @@ public: IngredientData *getIngredientHeldByIndex(int idx) const; IngredientData *getIngredientDataByIndex(int idx); - void applyIngredientEffects(IngredientData *data); + bool applyIngredientEffects(IngredientData *data); void loadIngredientData(const std::string &file); void loadIngredientDisplayNames(const std::string& file); diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 5f2de4e..6e2ddfd 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,20 @@ 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; + 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 +7408,8 @@ void Game::onCook() } refreshFoodSlots(true); +endcook: + AquariaGuiElement::canDirMoveGlobal = true; isCooking = false; @@ -8740,7 +8726,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..a9652de 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 }; @@ -2997,11 +3000,6 @@ luaFunc(entity_followPath) luaReturnNil(); } -luaFunc(getIngredientGfx) -{ - luaReturnStr(dsq->continuity.getIngredientGfx(getString(L, 1)).c_str()); -} - luaFunc(spawnIngredient) { int times = lua_tonumber(L, 4); @@ -6728,6 +6726,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 +7709,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 +7957,7 @@ static const struct { luaRegister(reconstructEntityGrid), luaRegister(ing_hasIET), + luaRegister(ing_getIngredientName), luaRegister(esetv), luaRegister(esetvf), @@ -8196,8 +8278,6 @@ static const struct { luaRegister(registerSporeDrop), - luaRegister(getIngredientGfx), - luaRegister(spawnIngredient), luaRegister(spawnAllIngredients), luaRegister(spawnParticleEffect), @@ -8690,6 +8770,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 +8837,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 +10064,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); From 25727244ad2437ebf424c983f6f04ef4789c45cb Mon Sep 17 00:00:00 2001 From: fgenesis Date: Thu, 20 Jun 2013 05:15:07 +0200 Subject: [PATCH 4/9] Little correction to prev commit Only handle cooking failure if the function call was successful. Otherwise, fallback to SeaLoaf. --- Aquaria/Game.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 6e2ddfd..3270fbc 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -7221,11 +7221,13 @@ void Game::onCook() const char *p2 = cookList[1]->name.c_str(); const char *p3 = cookList.size() >= 3 ? cookList[2]->name.c_str() : ""; std::string ingname; - cookingScript->call("cookFailure", p1, p2, p3, &ingname); - if(ingname.length()) - data = dsq->continuity.getIngredientDataByName(ingname); - if(!data) - goto endcook; + if(cookingScript->call("cookFailure", p1, p2, p3, &ingname)) + { + if(ingname.length()) + data = dsq->continuity.getIngredientDataByName(ingname); + if(!data) + goto endcook; + } } if(!data) From 54d609a8b507ddcab2127b88735e70adf07c1091 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Thu, 20 Jun 2013 20:01:51 +0200 Subject: [PATCH 5/9] Make avatar respect maxspeed lerp, allow changing speed multiplier via script. Some extra functions. Add one additional not-timed speed multiplier that also ignores influence by currents. Lua functions added: - avatar_setSpeedMult(num, time) - avatar_setSpeedMult2(num) - avatar_getSpeedMult() - avatar_getSpeedMult2() - entity_isInCurrent(entity) - entity_getNumTargetPoints(entity) --- Aquaria/Avatar.cpp | 10 +++------- Aquaria/Continuity.cpp | 1 + Aquaria/DSQ.h | 2 ++ Aquaria/ScriptInterface.cpp | 40 +++++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 7 deletions(-) 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 1a39f32..ed509af 100644 --- a/Aquaria/Continuity.cpp +++ b/Aquaria/Continuity.cpp @@ -3209,6 +3209,7 @@ void Continuity::reset() //worldMapTiles.clear(); speedMult = biteMult = fishPoison = defenseMult = 1; + speedMult2 = 1; poison = 0; energyMult = 0; light = petPower = 0; diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index b4df465..777a11b 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -1102,6 +1102,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/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index a9652de..856f1fb 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -2898,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)); @@ -3208,6 +3230,11 @@ luaFunc(entity_checkSplash) luaReturnBool(ret); } +luaFunc(entity_isInCurrent) +{ + Entity *e = entity(L); + luaReturnBool(e ? e->isInCurrent() : false); +} luaFunc(entity_isUnderWater) { @@ -5609,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; @@ -8066,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), @@ -8453,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), From 416b521a12c935d27db2c9fe9904bece5a11533a Mon Sep 17 00:00:00 2001 From: fgenesis Date: Thu, 20 Jun 2013 21:39:17 +0200 Subject: [PATCH 6/9] Initial support for loading android save files. Apparently there is a new map with the index 55 -- a related entry was added to the worldmap.txt file to prevent data loss, just in case. field is not yet handled missing. Hopefully the resulting format can be loaded on android without problems, especially because both "ingr" and "ingrNames" fields appear in the StartData tag now. --- Aquaria/Continuity.cpp | 37 ++++++++++++++++++++++++++- files/data/worldmap.txt | 56 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 files/data/worldmap.txt diff --git a/Aquaria/Continuity.cpp b/Aquaria/Continuity.cpp index ed509af..87514f2 100644 --- a/Aquaria/Continuity.cpp +++ b/Aquaria/Continuity.cpp @@ -2461,6 +2461,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); @@ -2479,6 +2480,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++) { @@ -2551,6 +2562,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; @@ -2810,7 +2824,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; } @@ -2853,6 +2869,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")); @@ -2916,6 +2949,8 @@ void Continuity::loadFile(int slot) } } + // TODO ANDROID: "ch" field + if (startData->Attribute("h")) { int read = atoi(startData->Attribute("h")); 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 From fe5f6faa466d67525297456567cba1e68c8446d8 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Fri, 21 Jun 2013 00:40:19 +0200 Subject: [PATCH 7/9] More save data compat with android version (world map gem data) --- Aquaria/Continuity.cpp | 81 ++++++++++++++++++++++++++++++++++++++---- Aquaria/DSQ.h | 1 + 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/Aquaria/Continuity.cpp b/Aquaria/Continuity.cpp index 87514f2..8cff2f3 100644 --- a/Aquaria/Continuity.cpp +++ b/Aquaria/Continuity.cpp @@ -2356,15 +2356,32 @@ 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); @@ -2748,6 +2765,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"); @@ -2785,6 +2803,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()); @@ -3134,6 +3200,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 diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 777a11b..3886e1d 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; }; From 46516eefc8594f35f57c561e2f8841bb27f7cc64 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Fri, 21 Jun 2013 00:41:07 +0200 Subject: [PATCH 8/9] ooops --- Aquaria/Continuity.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Aquaria/Continuity.cpp b/Aquaria/Continuity.cpp index 8cff2f3..11a9e39 100644 --- a/Aquaria/Continuity.cpp +++ b/Aquaria/Continuity.cpp @@ -2361,6 +2361,7 @@ void Continuity::saveFile(int slot, Vector position, unsigned char *scrShotData, // 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() << " "; @@ -2381,6 +2382,7 @@ void Continuity::saveFile(int slot, Vector position, unsigned char *scrShotData, os << spacesToUnderscores((*i).userString) << " "; } gems.SetAttribute("d", os.str()); + */ } doc.InsertEndChild(gems); From 2c99f010a475ac17aecd7cacf994cc322fea6e78 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Fri, 21 Jun 2013 03:33:35 +0200 Subject: [PATCH 9/9] Fixes to scripted ingredients, now it actually works --- Aquaria/Continuity.cpp | 77 +++++++++++++++++++++++------------------- Aquaria/DSQ.cpp | 1 + Aquaria/DSQ.h | 1 + 3 files changed, 45 insertions(+), 34 deletions(-) diff --git a/Aquaria/Continuity.cpp b/Aquaria/Continuity.cpp index 11a9e39..3a1ed8c 100644 --- a/Aquaria/Continuity.cpp +++ b/Aquaria/Continuity.cpp @@ -850,6 +850,7 @@ bool Continuity::applyIngredientEffects(IngredientData *data) if(dsq->game->cookingScript) dsq->game->cookingScript->call("useIngredient", data->name.c_str(), &eaten); } + break; default: { char str[256]; @@ -921,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; @@ -961,7 +999,7 @@ void Continuity::loadIngredientData(const std::string &file) if (p1 != std::string::npos && p2 != std::string::npos) { effects = effects.substr(p1+1, p2-(p1+1)); - SimpleIStringStream fxLine(effects.c_str(), SimpleIStringStream::REUSE); + std::istringstream fxLine(effects); std::string bit; while (fxLine >> bit) { @@ -1075,7 +1113,7 @@ void Continuity::loadIngredientData(const std::string &file) if(extradata) { - while (in >> line) + while (std::getline(in, line)) { SimpleIStringStream inLine(line.c_str(), SimpleIStringStream::REUSE); int maxAmount = MAX_INGREDIENT_AMOUNT; @@ -1084,7 +1122,7 @@ void Continuity::loadIngredientData(const std::string &file) if (name == "==Recipes==") { recipes = true; - continue; + break; } IngredientData *data = getIngredientDataByName(name); if(!data) @@ -3343,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 31f1b97..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') { diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 3886e1d..b4a6461 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -1065,6 +1065,7 @@ public: bool applyIngredientEffects(IngredientData *data); + void loadIngredientData(); void loadIngredientData(const std::string &file); void loadIngredientDisplayNames(const std::string& file); bool hasIngredients() const { return !ingredients.empty(); }