Refactored Map Data access so that other locations in code no longer had write abilities to the map data. Changed permanent exit zone spawning to a temporary. Fix equipment items being duplicated due to sorted inventory not being in sync with actual inventory.
This commit is contained in:
parent
7162b151e4
commit
5c83a41a86
@ -52,6 +52,19 @@
|
|||||||
],
|
],
|
||||||
"valuesAsFlags": false
|
"valuesAsFlags": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"color": "#ffa45f5f",
|
||||||
|
"drawFill": true,
|
||||||
|
"id": 36,
|
||||||
|
"members": [
|
||||||
|
],
|
||||||
|
"name": "BossArena",
|
||||||
|
"type": "class",
|
||||||
|
"useAs": [
|
||||||
|
"property",
|
||||||
|
"object"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"color": "#ff290aa4",
|
"color": "#ff290aa4",
|
||||||
"drawFill": true,
|
"drawFill": true,
|
||||||
|
@ -806,7 +806,7 @@ void AiL::PopulateRenderLists(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ZoneData&zone:MAP_DATA[GetCurrentLevel()].ZoneData["EndZone"]){
|
for(const ZoneData&zone:GetZones().at("EndZone")){
|
||||||
if(zone.isUpper){
|
if(zone.isUpper){
|
||||||
upperEndZones.push_back(zone);
|
upperEndZones.push_back(zone);
|
||||||
}else{
|
}else{
|
||||||
@ -1744,6 +1744,7 @@ void AiL::LoadLevel(MapName map){
|
|||||||
foregroundTileGroups.clear();
|
foregroundTileGroups.clear();
|
||||||
upperForegroundTileGroups.clear();
|
upperForegroundTileGroups.clear();
|
||||||
MONSTER_LIST.clear();
|
MONSTER_LIST.clear();
|
||||||
|
ZONE_LIST.clear();
|
||||||
GameEvent::events.clear();
|
GameEvent::events.clear();
|
||||||
worldColor=WHITE;
|
worldColor=WHITE;
|
||||||
worldColorFunc=[&](vi2d pos){return game->worldColor;};
|
worldColorFunc=[&](vi2d pos){return game->worldColor;};
|
||||||
@ -1756,12 +1757,15 @@ void AiL::LoadLevel(MapName map){
|
|||||||
totalBossEncounterMobs=0;
|
totalBossEncounterMobs=0;
|
||||||
Inventory::Clear("Monster Loot");
|
Inventory::Clear("Monster Loot");
|
||||||
Inventory::Clear("Stage Loot");
|
Inventory::Clear("Stage Loot");
|
||||||
|
|
||||||
GetPlayer()->hp=GetPlayer()->GetMaxHealth();
|
GetPlayer()->hp=GetPlayer()->GetMaxHealth();
|
||||||
GetPlayer()->mana=GetPlayer()->GetMaxMana();
|
GetPlayer()->mana=GetPlayer()->GetMaxMana();
|
||||||
GetPlayer()->SetState(State::NORMAL);
|
GetPlayer()->SetState(State::NORMAL);
|
||||||
GetPlayer()->GetCastInfo()={};
|
GetPlayer()->GetCastInfo()={};
|
||||||
GetPlayer()->ResetAccumulatedXP();
|
GetPlayer()->ResetAccumulatedXP();
|
||||||
|
|
||||||
|
ZONE_LIST=game->MAP_DATA[game->GetCurrentLevel()].ZoneData;
|
||||||
|
|
||||||
#pragma region Reset Environmental Audio
|
#pragma region Reset Environmental Audio
|
||||||
for(EnvironmentalAudio&audio:MAP_DATA[map].environmentalAudioData){
|
for(EnvironmentalAudio&audio:MAP_DATA[map].environmentalAudioData){
|
||||||
audio.Deactivate();
|
audio.Deactivate();
|
||||||
@ -2338,6 +2342,12 @@ void AiL::InitializeLevels(){
|
|||||||
InitializeLevel("map_path"_S+DATA["Levels"][key]["Map File"].GetString(),key);
|
InitializeLevel("map_path"_S+DATA["Levels"][key]["Map File"].GetString(),key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<std::string>cpNames;
|
||||||
|
for(ConnectionPoint&cp:State_OverworldMap::connections){
|
||||||
|
if(cpNames.count(cp.name)>0)ERR(std::format("WARNING! More than one connection point has the same name: {} THIS IS NOT ALLOWED!",cp.name));
|
||||||
|
cpNames.insert(cp.name);
|
||||||
|
}
|
||||||
|
|
||||||
for(ConnectionPoint&cp:State_OverworldMap::connections){
|
for(ConnectionPoint&cp:State_OverworldMap::connections){
|
||||||
if(cp.levelDataExists)continue;
|
if(cp.levelDataExists)continue;
|
||||||
if(VisualNovel::storyLevelData.count(cp.map)){ //Visual novel story data for story levels.
|
if(VisualNovel::storyLevelData.count(cp.map)){ //Visual novel story data for story levels.
|
||||||
@ -2961,3 +2971,25 @@ void AiL::SetWorldColor(Pixel worldCol){
|
|||||||
const Pixel&AiL::GetWorldColor()const{
|
const Pixel&AiL::GetWorldColor()const{
|
||||||
return worldColor;
|
return worldColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::map<std::string,std::vector<::ZoneData>>&AiL::GetZones(const std::string_view mapName)const{
|
||||||
|
if(GetCurrentMapDisplayName()==mapName)return GetZones();
|
||||||
|
return MAP_DATA.at(std::string(mapName)).ZoneData;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::map<std::string,std::vector<::ZoneData>>&AiL::GetZones()const{
|
||||||
|
return ZONE_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AiL::AddZone(const std::string_view zoneName,const ZoneData&zone){
|
||||||
|
if(ZONE_LIST.count(std::string(zoneName))==0)ERR(std::format("WARNING! Trying to add non-existent Zone Key {} to zone list of map {}. THIS IS NOT ALLOWED!",zoneName,std::string(GetCurrentMapName())));
|
||||||
|
ZONE_LIST[std::string(zoneName)].push_back(zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string_view AiL::GetCurrentMapDisplayName()const{
|
||||||
|
return GetCurrentMap().GetMapDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t AiL::BossEncounterMobCount()const{
|
||||||
|
return totalBossEncounterMobs;
|
||||||
|
}
|
@ -142,6 +142,7 @@ private:
|
|||||||
DynamicCounter manaCounter;
|
DynamicCounter manaCounter;
|
||||||
Pixel worldColor=WHITE;
|
Pixel worldColor=WHITE;
|
||||||
std::function<Pixel(vi2d)>worldColorFunc=[](vi2d pos){return WHITE;};
|
std::function<Pixel(vi2d)>worldColorFunc=[](vi2d pos){return WHITE;};
|
||||||
|
std::map<std::string,std::vector<::ZoneData>>ZONE_LIST;
|
||||||
|
|
||||||
void ValidateGameStatus();
|
void ValidateGameStatus();
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
@ -223,11 +224,13 @@ public:
|
|||||||
void DisplayBossEncounterInfo();
|
void DisplayBossEncounterInfo();
|
||||||
void BossDamageDealt(int damage);
|
void BossDamageDealt(int damage);
|
||||||
void ReduceBossEncounterMobCount();
|
void ReduceBossEncounterMobCount();
|
||||||
|
const uint8_t BossEncounterMobCount()const;
|
||||||
void InitializeGraphics();
|
void InitializeGraphics();
|
||||||
void RenderVersionInfo();
|
void RenderVersionInfo();
|
||||||
const Map&GetCurrentMap()const;
|
const Map&GetCurrentMap()const;
|
||||||
const MapTag&GetCurrentMapData()const;
|
const MapTag&GetCurrentMapData()const;
|
||||||
const MapName&GetCurrentMapName()const;
|
const MapName&GetCurrentMapName()const;
|
||||||
|
const std::string_view GetCurrentMapDisplayName()const;
|
||||||
int GetCurrentChapter();
|
int GetCurrentChapter();
|
||||||
void SetChapter(int chapter);
|
void SetChapter(int chapter);
|
||||||
const std::weak_ptr<Item>GetLoadoutItem(int slot);
|
const std::weak_ptr<Item>GetLoadoutItem(int slot);
|
||||||
@ -248,6 +251,11 @@ public:
|
|||||||
void SetWorldColorFunc(std::function<Pixel(vi2d)>func);
|
void SetWorldColorFunc(std::function<Pixel(vi2d)>func);
|
||||||
void SetWorldColor(Pixel worldCol);
|
void SetWorldColor(Pixel worldCol);
|
||||||
const Pixel&GetWorldColor()const;
|
const Pixel&GetWorldColor()const;
|
||||||
|
//Returns the zones in the current stage
|
||||||
|
const std::map<std::string,std::vector<::ZoneData>>&GetZones()const;
|
||||||
|
//Returns the zones of any given stage
|
||||||
|
const std::map<std::string,std::vector<::ZoneData>>&GetZones(const std::string_view mapName)const;
|
||||||
|
void AddZone(const std::string_view zoneName,const ZoneData&zone);
|
||||||
|
|
||||||
struct TileGroupData{
|
struct TileGroupData{
|
||||||
vi2d tilePos;
|
vi2d tilePos;
|
||||||
|
@ -79,7 +79,7 @@ void EnvironmentalAudio::Deactivate(){
|
|||||||
activated=false;
|
activated=false;
|
||||||
}
|
}
|
||||||
void EnvironmentalAudio::UpdateEnvironmentalAudio(){
|
void EnvironmentalAudio::UpdateEnvironmentalAudio(){
|
||||||
for(const EnvironmentalAudio&aud:game->GetCurrentMap().environmentalAudioData){
|
for(const EnvironmentalAudio&aud:game->GetCurrentMap().GetEnvironmentalAudio()){
|
||||||
EnvironmentalAudio&audio=const_cast<EnvironmentalAudio&>(aud);
|
EnvironmentalAudio&audio=const_cast<EnvironmentalAudio&>(aud);
|
||||||
audio.Update();
|
audio.Update();
|
||||||
}
|
}
|
||||||
|
@ -409,6 +409,7 @@ std::weak_ptr<Item>Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){
|
|||||||
std::shared_ptr<Item>newItem=(*_inventory.insert({it,std::make_shared<Item>(1,it)})).second;
|
std::shared_ptr<Item>newItem=(*_inventory.insert({it,std::make_shared<Item>(1,it)})).second;
|
||||||
newItem->RandomizeStats();
|
newItem->RandomizeStats();
|
||||||
InsertIntoSortedInv(newItem);
|
InsertIntoSortedInv(newItem);
|
||||||
|
InsertIntoStageInventoryCategory(newItem,monsterDrop);
|
||||||
itemPtr=newItem;
|
itemPtr=newItem;
|
||||||
}
|
}
|
||||||
goto SkipAddingStackableItem;
|
goto SkipAddingStackableItem;
|
||||||
@ -418,6 +419,7 @@ std::weak_ptr<Item>Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){
|
|||||||
if(!_inventory.count(it)){
|
if(!_inventory.count(it)){
|
||||||
std::shared_ptr<Item>newItem=(*_inventory.insert({it,std::make_shared<Item>(amt,it)})).second;
|
std::shared_ptr<Item>newItem=(*_inventory.insert({it,std::make_shared<Item>(amt,it)})).second;
|
||||||
InsertIntoSortedInv(newItem);
|
InsertIntoSortedInv(newItem);
|
||||||
|
InsertIntoStageInventoryCategory(newItem,monsterDrop);
|
||||||
itemPtr=newItem;
|
itemPtr=newItem;
|
||||||
}else{
|
}else{
|
||||||
auto inventory=_inventory.equal_range(it);
|
auto inventory=_inventory.equal_range(it);
|
||||||
@ -429,7 +431,6 @@ std::weak_ptr<Item>Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){
|
|||||||
}
|
}
|
||||||
|
|
||||||
SkipAddingStackableItem:
|
SkipAddingStackableItem:
|
||||||
InsertIntoStageInventoryCategory(it,amt,monsterDrop);
|
|
||||||
return itemPtr;
|
return itemPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,8 +500,12 @@ bool Inventory::RemoveItem(std::weak_ptr<Item>itemRef,ITCategory inventory,uint3
|
|||||||
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
|
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
|
||||||
if(!itemAmt)return false;
|
if(!itemAmt)return false;
|
||||||
|
|
||||||
|
std::string itemName=itemRef.lock()->DisplayName();
|
||||||
|
|
||||||
if (amt>=itemAmt){
|
if (amt>=itemAmt){
|
||||||
|
size_t invSize=inv.size();
|
||||||
inv.erase(inv.begin()+count); //Clears it from the detected sorted inventory as well!
|
inv.erase(inv.begin()+count); //Clears it from the detected sorted inventory as well!
|
||||||
|
if(invSize-1!=inv.size())ERR(std::format("WARNING! Did not properly erase {} from sorted inventory {}",itemName,inventory));
|
||||||
if(!eraseFromLootWindow){ //We must clear out the item AFTER we've updated context-sensitive inventories because they may be borrowing a ref from this structure!!!
|
if(!eraseFromLootWindow){ //We must clear out the item AFTER we've updated context-sensitive inventories because they may be borrowing a ref from this structure!!!
|
||||||
_inventory.erase(itemRef.lock()->ActualName());
|
_inventory.erase(itemRef.lock()->ActualName());
|
||||||
}
|
}
|
||||||
@ -511,6 +516,7 @@ bool Inventory::RemoveItem(std::weak_ptr<Item>itemRef,ITCategory inventory,uint3
|
|||||||
}else{
|
}else{
|
||||||
if(itemRef.lock()->IsEquippable()){ //Since equipment doesn't stack, if we have more than one piece we have to still remove that piece.
|
if(itemRef.lock()->IsEquippable()){ //Since equipment doesn't stack, if we have more than one piece we have to still remove that piece.
|
||||||
bool found=false;
|
bool found=false;
|
||||||
|
|
||||||
size_t erased=std::erase_if(_inventory,[&](const std::pair<const IT,std::shared_ptr<Item>>data){
|
size_t erased=std::erase_if(_inventory,[&](const std::pair<const IT,std::shared_ptr<Item>>data){
|
||||||
if(!found&&data.second==itemRef){
|
if(!found&&data.second==itemRef){
|
||||||
found=true;
|
found=true;
|
||||||
@ -519,7 +525,9 @@ bool Inventory::RemoveItem(std::weak_ptr<Item>itemRef,ITCategory inventory,uint3
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
if(erased!=1)ERR(std::format("Did not erase a single element, instead erased {} elements.",erased));
|
if(erased!=1)ERR(std::format("Did not erase a single element, instead erased {} elements.",erased));
|
||||||
|
size_t invSize=inv.size();
|
||||||
inv.erase(inv.begin()+count); //Clears it from the detected sorted inventory as well!
|
inv.erase(inv.begin()+count); //Clears it from the detected sorted inventory as well!
|
||||||
|
if(invSize-1!=inv.size())ERR(std::format("WARNING! Did not properly erase {} from sorted inventory {}",itemName,inventory));
|
||||||
Menu::InventorySlotsUpdated(inventory);
|
Menu::InventorySlotsUpdated(inventory);
|
||||||
return true;
|
return true;
|
||||||
}else{
|
}else{
|
||||||
@ -545,17 +553,22 @@ void Inventory::InsertIntoSortedInv(std::shared_ptr<Item>itemRef){
|
|||||||
Menu::InventorySlotsUpdated(itemRef->Category());
|
Menu::InventorySlotsUpdated(itemRef->Category());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inventory::InsertIntoStageInventoryCategory(IT item,uint32_t amt,bool monsterDrop){
|
void Inventory::InsertIntoStageInventoryCategory(std::shared_ptr<Item>itemRef,const bool monsterDrop){
|
||||||
std::string stageInventoryCategory="Stage Loot";
|
std::string stageInventoryCategory="Stage Loot";
|
||||||
if(monsterDrop){
|
if(monsterDrop){
|
||||||
stageInventoryCategory="Monster Loot";
|
stageInventoryCategory="Monster Loot";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Item>>&inv=sortedInv.at(stageInventoryCategory);
|
std::vector<std::shared_ptr<Item>>&inv=sortedInv.at(stageInventoryCategory);
|
||||||
std::vector<std::shared_ptr<Item>>::iterator it=std::find(inv.begin(),inv.end(),std::make_shared<Item>(amt,item)); //Uses operator== to compare if this item does exist in a stage/monster loot inventory already. We just make an in-place shared pointer of an item to compare with.
|
if(itemRef->IsEquippable()){ //We cannot stack items! They are always individual.
|
||||||
if(it!=inv.end()){
|
inv.push_back(itemRef);
|
||||||
(*it)->amt+=amt;
|
|
||||||
}else{
|
}else{
|
||||||
inv.push_back(std::make_shared<Item>(amt,item));
|
std::vector<std::shared_ptr<Item>>::iterator it=std::find(inv.begin(),inv.end(),itemRef); //Uses operator== to compare if this item does exist in a stage/monster loot inventory already. We just make an in-place shared pointer of an item to compare with.
|
||||||
|
if(it!=inv.end()){
|
||||||
|
(*it)->amt+=itemRef->Amt();
|
||||||
|
}else{
|
||||||
|
inv.push_back(itemRef);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Menu::InventorySlotsUpdated(stageInventoryCategory);
|
Menu::InventorySlotsUpdated(stageInventoryCategory);
|
||||||
}
|
}
|
||||||
@ -692,10 +705,17 @@ const bool Item::IsBlank()const{
|
|||||||
|
|
||||||
void Inventory::Clear(ITCategory itemCategory){
|
void Inventory::Clear(ITCategory itemCategory){
|
||||||
std::vector<std::shared_ptr<Item>>itemList=get(itemCategory); //We have to make a copy here because RemoveItem() will modify the list provided by get() inline.
|
std::vector<std::shared_ptr<Item>>itemList=get(itemCategory); //We have to make a copy here because RemoveItem() will modify the list provided by get() inline.
|
||||||
|
if(itemCategory=="Monster Loot"||itemCategory=="Stage Loot"){
|
||||||
|
while(sortedInv[itemCategory].size()>0){
|
||||||
|
RemoveItem(sortedInv[itemCategory].front(),itemCategory,sortedInv[itemCategory].front()->Amt());
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
{
|
||||||
for(std::shared_ptr<Item>&item:itemList){
|
for(std::shared_ptr<Item>&item:itemList){
|
||||||
RemoveItem(item,itemCategory,item->Amt());
|
RemoveItem(item,itemCategory,item->Amt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ItemOverlay::ItemOverlay(ItemInfo item)
|
ItemOverlay::ItemOverlay(ItemInfo item)
|
||||||
:it(item),width("ItemDrop.Item Drop Scale"_F*24+4+game->GetTextSizeProp(item.Name()).x*0.5f){
|
:it(item),width("ItemDrop.Item Drop Scale"_F*24+4+game->GetTextSizeProp(item.Name()).x*0.5f){
|
||||||
@ -1101,8 +1121,7 @@ void Item::RandomizeStats(){
|
|||||||
randomizedStats=it->RandomizeStats();
|
randomizedStats=it->RandomizeStats();
|
||||||
};
|
};
|
||||||
|
|
||||||
const Stats ItemInfo::GetMinStats()const{
|
const Stats ItemInfo::GetMinStats()const{return minStats;
|
||||||
return minStats;
|
|
||||||
}
|
}
|
||||||
const Stats ItemInfo::GetMaxStats()const{
|
const Stats ItemInfo::GetMaxStats()const{
|
||||||
return maxStats;
|
return maxStats;
|
||||||
@ -1130,3 +1149,11 @@ const EventName&ItemInfo::UseSound()const{
|
|||||||
const EventName&Item::UseSound()const{
|
const EventName&Item::UseSound()const{
|
||||||
return it->UseSound();
|
return it->UseSound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::shared_ptr<Item>>Inventory::GetInventory(){
|
||||||
|
std::vector<std::shared_ptr<Item>>itemList;
|
||||||
|
for(size_t itemCount=0;auto&[itemName,item]:Inventory::_inventory){
|
||||||
|
itemList.push_back(item);
|
||||||
|
}
|
||||||
|
return itemList;
|
||||||
|
}
|
@ -247,6 +247,8 @@ public:
|
|||||||
static EquipSlot GetSlotEquippedIn(const std::weak_ptr<Item>it);
|
static EquipSlot GetSlotEquippedIn(const std::weak_ptr<Item>it);
|
||||||
static std::weak_ptr<Item>GetEquip(EquipSlot slot);
|
static std::weak_ptr<Item>GetEquip(EquipSlot slot);
|
||||||
static const std::map<ItemSet,int>GetEquippedItemSets();
|
static const std::map<ItemSet,int>GetEquippedItemSets();
|
||||||
|
//Gets all items currently on inventory (Ignores Stage Loot and Monster Loot Inventories)
|
||||||
|
static const std::vector<std::shared_ptr<Item>>GetInventory();
|
||||||
|
|
||||||
static bool SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2);
|
static bool SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2);
|
||||||
//Makes sure this is a valid category. Will error out if it doesn't exist! Use for ERROR HANDLING!
|
//Makes sure this is a valid category. Will error out if it doesn't exist! Use for ERROR HANDLING!
|
||||||
@ -256,7 +258,7 @@ public:
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
static void InsertIntoSortedInv(std::shared_ptr<Item>itemRef);
|
static void InsertIntoSortedInv(std::shared_ptr<Item>itemRef);
|
||||||
static void InsertIntoStageInventoryCategory(IT item,uint32_t amt,bool monsterDrop);
|
static void InsertIntoStageInventoryCategory(std::shared_ptr<Item>itemRef,const bool monsterDrop);
|
||||||
static bool ExecuteAction(IT item);
|
static bool ExecuteAction(IT item);
|
||||||
static std::multimap<IT,std::shared_ptr<Item>>_inventory;
|
static std::multimap<IT,std::shared_ptr<Item>>_inventory;
|
||||||
static std::map<EquipSlot,std::weak_ptr<Item>>equipment;
|
static std::map<EquipSlot,std::weak_ptr<Item>>equipment;
|
||||||
|
@ -669,6 +669,17 @@ void Monster::OnDeath(){
|
|||||||
animation.ChangeState(internal_animState,GetDeathAnimationName());
|
animation.ChangeState(internal_animState,GetDeathAnimationName());
|
||||||
if(isBoss){
|
if(isBoss){
|
||||||
game->ReduceBossEncounterMobCount();
|
game->ReduceBossEncounterMobCount();
|
||||||
|
if(game->BossEncounterMobCount()==0){
|
||||||
|
ZoneData exitRing{geom2d::rect<int>{vi2d{GetPos()-vf2d{"boss_spawn_ring_radius"_F,"boss_spawn_ring_radius"_F}},vi2d{"boss_spawn_ring_radius"_I*2,"boss_spawn_ring_radius"_I*2}},OnUpperLevel()};
|
||||||
|
|
||||||
|
const geom2d::rect<int>arenaBounds=game->GetZones().at("BossArena")[0].zone;
|
||||||
|
geom2d::rect<int>clampedArena{vi2d(arenaBounds.pos+"boss_spawn_ring_radius"_I),vi2d(arenaBounds.size-"boss_spawn_ring_radius"_I*2)};
|
||||||
|
|
||||||
|
exitRing.zone.pos.x=std::clamp(exitRing.zone.pos.x,clampedArena.pos.x,clampedArena.pos.x+clampedArena.size.x);
|
||||||
|
exitRing.zone.pos.y=std::clamp(exitRing.zone.pos.y,clampedArena.pos.y,clampedArena.pos.y+clampedArena.size.y);
|
||||||
|
|
||||||
|
game->AddZone("EndZone",exitRing); //Create a 144x144 ring around the dead boss.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hasStrategyDeathFunction){
|
if(hasStrategyDeathFunction){
|
||||||
|
@ -50,7 +50,7 @@ void Pathfinding::Initialize(){
|
|||||||
for (int y = 0; y < game->GetCurrentMapData().height*24; y+=gridSpacing.y)
|
for (int y = 0; y < game->GetCurrentMapData().height*24; y+=gridSpacing.y)
|
||||||
{
|
{
|
||||||
bool tileIsEmpty=true;
|
bool tileIsEmpty=true;
|
||||||
for(const LayerTag&layer:game->GetCurrentMap().LayerData){
|
for(const LayerTag&layer:game->GetCurrentMap().GetLayers()){
|
||||||
int tileID=layer.tiles[y/24][x/24]-1;
|
int tileID=layer.tiles[y/24][x/24]-1;
|
||||||
if(tileID!=-1){
|
if(tileID!=-1){
|
||||||
tileIsEmpty=false;
|
tileIsEmpty=false;
|
||||||
|
@ -965,11 +965,11 @@ float Player::GetEndZoneStandTime(){
|
|||||||
|
|
||||||
void Player::CheckEndZoneCollision(){
|
void Player::CheckEndZoneCollision(){
|
||||||
auto HasZoneData=[&](){
|
auto HasZoneData=[&](){
|
||||||
return game->MAP_DATA[game->GetCurrentLevel()].ZoneData.count("EndZone");
|
return game->GetZones().count("EndZone");
|
||||||
};
|
};
|
||||||
|
|
||||||
if(IsOutOfCombat()&&HasZoneData()){
|
if(IsOutOfCombat()&&HasZoneData()){
|
||||||
for(ZoneData&zone:game->MAP_DATA[game->GetCurrentLevel()].ZoneData.at("EndZone")){
|
for(const ZoneData&zone:game->GetZones().at("EndZone")){
|
||||||
if(zone.isUpper==upperLevel&&geom2d::overlaps(GetPos(),zone.zone)){
|
if(zone.isUpper==upperLevel&&geom2d::overlaps(GetPos(),zone.zone)){
|
||||||
endZoneStandTime+=game->GetElapsedTime();
|
endZoneStandTime+=game->GetElapsedTime();
|
||||||
if(endZoneStandTime>="Player.End Zone Wait Time"_F){
|
if(endZoneStandTime>="Player.End Zone Wait Time"_F){
|
||||||
|
@ -80,8 +80,7 @@ const void SaveFile::SaveGame(){
|
|||||||
std::filesystem::create_directories("save_file_path"_S);
|
std::filesystem::create_directories("save_file_path"_S);
|
||||||
utils::datafile saveFile;
|
utils::datafile saveFile;
|
||||||
utils::datafile::INITIAL_SETUP_COMPLETE=false;
|
utils::datafile::INITIAL_SETUP_COMPLETE=false;
|
||||||
for(size_t itemCount=0;auto&[cat,items]:Inventory::sortedInv){
|
for(size_t itemCount=0;auto&item:Inventory::GetInventory()){
|
||||||
for(std::shared_ptr<Item>&item:items){
|
|
||||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Amt"].SetInt(item->Amt());
|
saveFile["Items"][std::format("Item[{}]",itemCount)]["Amt"].SetInt(item->Amt());
|
||||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Enhancement Level"].SetInt(item->EnhancementLevel());
|
saveFile["Items"][std::format("Item[{}]",itemCount)]["Enhancement Level"].SetInt(item->EnhancementLevel());
|
||||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Item Name"].SetString(item->ActualName());
|
saveFile["Items"][std::format("Item[{}]",itemCount)]["Item Name"].SetString(item->ActualName());
|
||||||
@ -96,7 +95,6 @@ const void SaveFile::SaveGame(){
|
|||||||
}
|
}
|
||||||
itemCount++;
|
itemCount++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
saveFile["Player"]["Class"].SetString(game->GetPlayer()->GetClassName());
|
saveFile["Player"]["Class"].SetString(game->GetPlayer()->GetClassName());
|
||||||
saveFile["Player"]["Level"].SetInt(game->GetPlayer()->Level());
|
saveFile["Player"]["Level"].SetInt(game->GetPlayer()->Level());
|
||||||
saveFile["Player"]["Money"].SetInt(game->GetPlayer()->GetMoney());
|
saveFile["Player"]["Money"].SetInt(game->GetPlayer()->GetMoney());
|
||||||
|
@ -51,7 +51,7 @@ void State_LevelComplete::OnStateChange(GameState*prevState){
|
|||||||
}
|
}
|
||||||
Component<MenuLabel>(MenuType::LEVEL_COMPLETE,"Level EXP Gain Outline")->SetLabel(std::format("+{} Exp",game->GetPlayer()->GetAccumulatedXP()));
|
Component<MenuLabel>(MenuType::LEVEL_COMPLETE,"Level EXP Gain Outline")->SetLabel(std::format("+{} Exp",game->GetPlayer()->GetAccumulatedXP()));
|
||||||
game->GetPlayer()->AddXP(game->GetPlayer()->GetAccumulatedXP());
|
game->GetPlayer()->AddXP(game->GetPlayer()->GetAccumulatedXP());
|
||||||
for(const ItemMapData&data:game->GetCurrentMap().stageLoot){
|
for(const ItemMapData&data:game->GetCurrentMap().GetStageLoot()){
|
||||||
uint8_t amountDiff=data.maxAmt-data.minAmt;
|
uint8_t amountDiff=data.maxAmt-data.minAmt;
|
||||||
uint8_t randomAmt=data.maxAmt;
|
uint8_t randomAmt=data.maxAmt;
|
||||||
if(amountDiff>0){ //This check avoids division by zero.
|
if(amountDiff>0){ //This check avoids division by zero.
|
||||||
|
@ -95,6 +95,9 @@ struct ZoneData{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Map{
|
struct Map{
|
||||||
|
friend class AiL;
|
||||||
|
friend class TMXParser;
|
||||||
|
private:
|
||||||
MapTag MapData;
|
MapTag MapData;
|
||||||
std::string name;
|
std::string name;
|
||||||
Renderable*optimizedTile=nullptr;
|
Renderable*optimizedTile=nullptr;
|
||||||
@ -108,7 +111,15 @@ struct Map{
|
|||||||
std::set<std::string>spawns;
|
std::set<std::string>spawns;
|
||||||
std::map<int,SpawnerTag> SpawnerData; //Spawn groups have IDs, mobs associate which spawner they are tied to via this ID.
|
std::map<int,SpawnerTag> SpawnerData; //Spawn groups have IDs, mobs associate which spawner they are tied to via this ID.
|
||||||
std::map<std::string,std::vector<::ZoneData>> ZoneData;
|
std::map<std::string,std::vector<::ZoneData>> ZoneData;
|
||||||
|
const std::map<std::string,std::vector<::ZoneData>>&GetZones()const;
|
||||||
|
public:
|
||||||
|
const MapTag&GetMapData()const;
|
||||||
|
const std::string_view GetMapType()const;
|
||||||
|
const std::vector<ItemMapData>&GetStageLoot()const;
|
||||||
|
const std::vector<LayerTag>&GetLayers()const;
|
||||||
|
const std::vector<EnvironmentalAudio>&GetEnvironmentalAudio()const;
|
||||||
const MapName&GetMapName()const;
|
const MapName&GetMapName()const;
|
||||||
|
const std::string_view GetMapDisplayName()const;
|
||||||
std::string FormatLayerData(std::ostream& os, std::vector<LayerTag>tiles);
|
std::string FormatLayerData(std::ostream& os, std::vector<LayerTag>tiles);
|
||||||
std::string FormatSpawnerData(std::ostream& os, std::map<int,SpawnerTag>tiles);
|
std::string FormatSpawnerData(std::ostream& os, std::map<int,SpawnerTag>tiles);
|
||||||
friend std::ostream& operator << (std::ostream& os, Map& rhs);
|
friend std::ostream& operator << (std::ostream& os, Map& rhs);
|
||||||
@ -248,9 +259,30 @@ class TMXParser{
|
|||||||
}
|
}
|
||||||
return displayStr;
|
return displayStr;
|
||||||
}
|
}
|
||||||
|
const std::string_view Map::GetMapType()const{
|
||||||
|
return mapType;
|
||||||
|
}
|
||||||
const MapName&Map::GetMapName()const{
|
const MapName&Map::GetMapName()const{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
const MapTag&Map::GetMapData()const{
|
||||||
|
return MapData;
|
||||||
|
}
|
||||||
|
const std::vector<EnvironmentalAudio>&Map::GetEnvironmentalAudio()const{
|
||||||
|
return environmentalAudioData;
|
||||||
|
}
|
||||||
|
const std::map<std::string,std::vector<::ZoneData>>&Map::GetZones()const{
|
||||||
|
return ZoneData;
|
||||||
|
}
|
||||||
|
const std::vector<ItemMapData>&Map::GetStageLoot()const{
|
||||||
|
return stageLoot;
|
||||||
|
}
|
||||||
|
const std::vector<LayerTag>&Map::GetLayers()const{
|
||||||
|
return LayerData;
|
||||||
|
}
|
||||||
|
const std::string_view Map::GetMapDisplayName()const{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
std::ostream& operator <<(std::ostream& os, std::vector<XMLTag>& rhs) {
|
std::ostream& operator <<(std::ostream& os, std::vector<XMLTag>& rhs) {
|
||||||
for(XMLTag&tag:rhs){
|
for(XMLTag&tag:rhs){
|
||||||
os <<
|
os <<
|
||||||
@ -440,6 +472,12 @@ class TMXParser{
|
|||||||
|
|
||||||
std::string accumulator="";
|
std::string accumulator="";
|
||||||
|
|
||||||
|
//Initialize these so that they are valid entries for zones.
|
||||||
|
parsedMapInfo.ZoneData["LowerZone"];
|
||||||
|
parsedMapInfo.ZoneData["UpperZone"];
|
||||||
|
parsedMapInfo.ZoneData["EndZone"];
|
||||||
|
parsedMapInfo.ZoneData["BossArena"];
|
||||||
|
|
||||||
while (f.good()&&!infiniteMap) {
|
while (f.good()&&!infiniteMap) {
|
||||||
std::string data;
|
std::string data;
|
||||||
f>>data;
|
f>>data;
|
||||||
|
@ -25,6 +25,8 @@ Settings Menu
|
|||||||
- Implement escape menu during gameplay.
|
- Implement escape menu during gameplay.
|
||||||
- If you leave a stage, the stage complete window still shows up, showing only the loot you obtained that session.
|
- If you leave a stage, the stage complete window still shows up, showing only the loot you obtained that session.
|
||||||
|
|
||||||
|
- No equip sounds for weapons?
|
||||||
|
|
||||||
January 31st
|
January 31st
|
||||||
============
|
============
|
||||||
|
|
||||||
|
@ -54,14 +54,14 @@ void Test::is(std::string conditionStr,bool testResult){
|
|||||||
|
|
||||||
void Test::RunMapTests(){
|
void Test::RunMapTests(){
|
||||||
is("There are two LowerBridgeCollision zones in Campaign I-I",
|
is("There are two LowerBridgeCollision zones in Campaign I-I",
|
||||||
game->MAP_DATA.at("CAMPAIGN_1_1").ZoneData.count("LowerBridgeCollision")
|
game->GetZoneData("CAMPAIGN_1_1").count("LowerBridgeCollision")
|
||||||
&&game->MAP_DATA.at("CAMPAIGN_1_1").ZoneData.at("LowerBridgeCollision").size()>=2);
|
&&game->GetZoneData("CAMPAIGN_1_1").at("LowerBridgeCollision").size()>=2);
|
||||||
for(auto&[key,value]:game->MAP_DATA){
|
for(auto&[key,value]:game->MAP_DATA){
|
||||||
is("A Map type has been selected for map "+key,
|
is("A Map type has been selected for map "+key,
|
||||||
value.mapType!=""&&value.mapType!="Unspecified");
|
value.GetMapType()!=""&&value.GetMapType()!="Unspecified");
|
||||||
if(value.mapType=="Dungeon"){
|
if(value.GetMapType()=="Dungeon"){
|
||||||
is("There is an EndZone in Dungeon "+key,
|
is("There is an EndZone in Dungeon "+key,
|
||||||
value.ZoneData.count("EndZone"));
|
game->GetZones(key).count("EndZone"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -127,7 +127,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vf2d mapCenter=game->GetCurrentMap().MapData.MapSize*vf2d{float(game->GetCurrentMap().MapData.tilewidth),float(game->GetCurrentMap().MapData.tileheight)}/2.0f;
|
vf2d mapCenter=game->GetCurrentMap().GetMapData().MapSize*vf2d{float(game->GetCurrentMap().GetMapData().tilewidth),float(game->GetCurrentMap().GetMapData().tileheight)}/2.0f;
|
||||||
float distToCenter=geom2d::line<float>(m.GetPos(),mapCenter).length();
|
float distToCenter=geom2d::line<float>(m.GetPos(),mapCenter).length();
|
||||||
if(distToCenter>4.0f){
|
if(distToCenter>4.0f){
|
||||||
m.targetAcquireTimer=20.f;
|
m.targetAcquireTimer=20.f;
|
||||||
@ -204,7 +204,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
|
|||||||
vi2d wispSize={ConfigIntArr("Phase 2.Wisp Size",0),ConfigIntArr("Phase 2.Wisp Size",1)};
|
vi2d wispSize={ConfigIntArr("Phase 2.Wisp Size",0),ConfigIntArr("Phase 2.Wisp Size",1)};
|
||||||
|
|
||||||
float rowWidth=ConfigString(std::format("Wisp Pattern {}.Row[0]",wispPattern)).length()*wispSize.x; // Width of a wisp set in pixels.
|
float rowWidth=ConfigString(std::format("Wisp Pattern {}.Row[0]",wispPattern)).length()*wispSize.x; // Width of a wisp set in pixels.
|
||||||
float mapWidth=game->GetCurrentMap().MapData.MapSize.x*float(game->GetCurrentMap().MapData.tilewidth);
|
float mapWidth=game->GetCurrentMap().GetMapData().MapSize.x*float(game->GetCurrentMap().GetMapData().tilewidth);
|
||||||
int rowCount=Config(std::format("Wisp Pattern {}",wispPattern)).GetKeys().size();
|
int rowCount=Config(std::format("Wisp Pattern {}",wispPattern)).GetKeys().size();
|
||||||
for(float x=0;x<mapWidth;x+=wispSize.x){
|
for(float x=0;x<mapWidth;x+=wispSize.x){
|
||||||
for(int y=0;y<rowCount;y++){
|
for(int y=0;y<rowCount;y++){
|
||||||
@ -287,7 +287,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vf2d mapCenter=game->GetCurrentMap().MapData.MapSize*vf2d{float(game->GetCurrentMap().MapData.tilewidth),float(game->GetCurrentMap().MapData.tileheight)}/2.0f;
|
vf2d mapCenter=game->GetCurrentMap().GetMapData().MapSize*vf2d{float(game->GetCurrentMap().GetMapData().tilewidth),float(game->GetCurrentMap().GetMapData().tileheight)}/2.0f;
|
||||||
float distToCenter=geom2d::line<float>(m.GetPos(),mapCenter).length();
|
float distToCenter=geom2d::line<float>(m.GetPos(),mapCenter).length();
|
||||||
if(distToCenter>4.0f){
|
if(distToCenter>4.0f){
|
||||||
m.targetAcquireTimer=20.f;
|
m.targetAcquireTimer=20.f;
|
||||||
@ -317,8 +317,8 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
|
|||||||
m.AddBuff(COLLISION_KNOCKBACK_STRENGTH,10.f,ConfigFloat("Phase 3.Charge Attack Knockback Strength"));
|
m.AddBuff(COLLISION_KNOCKBACK_STRENGTH,10.f,ConfigFloat("Phase 3.Charge Attack Knockback Strength"));
|
||||||
m.target=geom2d::line<float>(m.GetPos(),game->GetPlayer()->GetPos()).upoint(2.0f);
|
m.target=geom2d::line<float>(m.GetPos(),game->GetPlayer()->GetPos()).upoint(2.0f);
|
||||||
//It's possible the charge forces the bear outside the map, so it will attempt to run forever on the clamped edges.
|
//It's possible the charge forces the bear outside the map, so it will attempt to run forever on the clamped edges.
|
||||||
m.target.x=std::clamp(m.target.x,0.f,float(game->GetCurrentMap().MapData.width*game->GetCurrentMap().MapData.tilewidth));
|
m.target.x=std::clamp(m.target.x,0.f,float(game->GetCurrentMap().GetMapData().width*game->GetCurrentMap().GetMapData().tilewidth));
|
||||||
m.target.y=std::clamp(m.target.y,0.f,float(game->GetCurrentMap().MapData.height*game->GetCurrentMap().MapData.tileheight));
|
m.target.y=std::clamp(m.target.y,0.f,float(game->GetCurrentMap().GetMapData().height*game->GetCurrentMap().GetMapData().tileheight));
|
||||||
m.F(A::TARGET_TIMER)=ConfigFloat("Phase 3.Charge Max Run Time");
|
m.F(A::TARGET_TIMER)=ConfigFloat("Phase 3.Charge Max Run Time");
|
||||||
m.F(A::CHARGE_COOLDOWN)=ConfigFloat("Phase 3.Charge Attack Cooldown");
|
m.F(A::CHARGE_COOLDOWN)=ConfigFloat("Phase 3.Charge Attack Cooldown");
|
||||||
m.PerformOtherAnimation(3);
|
m.PerformOtherAnimation(3);
|
||||||
@ -408,7 +408,7 @@ void Monster::STRATEGY::URSULE(Monster&m,float fElapsedTime,std::string strategy
|
|||||||
vi2d wispSize={ConfigIntArr("Phase 4.Wisp Size",0),ConfigIntArr("Phase 4.Wisp Size",1)};
|
vi2d wispSize={ConfigIntArr("Phase 4.Wisp Size",0),ConfigIntArr("Phase 4.Wisp Size",1)};
|
||||||
|
|
||||||
float rowWidth=ConfigString(std::format("Wisp Pattern {}.Row[0]",wispPattern)).length()*wispSize.x; // Width of a wisp set in pixels.
|
float rowWidth=ConfigString(std::format("Wisp Pattern {}.Row[0]",wispPattern)).length()*wispSize.x; // Width of a wisp set in pixels.
|
||||||
float mapWidth=game->GetCurrentMap().MapData.MapSize.x*float(game->GetCurrentMap().MapData.tilewidth);
|
float mapWidth=game->GetCurrentMap().GetMapData().MapSize.x*float(game->GetCurrentMap().GetMapData().tilewidth);
|
||||||
int rowCount=Config(std::format("Wisp Pattern {}",wispPattern)).GetKeys().size();
|
int rowCount=Config(std::format("Wisp Pattern {}",wispPattern)).GetKeys().size();
|
||||||
for(float x=0;x<mapWidth;x+=wispSize.x){
|
for(float x=0;x<mapWidth;x+=wispSize.x){
|
||||||
for(int y=0;y<rowCount;y++){
|
for(int y=0;y<rowCount;y++){
|
||||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 3
|
#define VERSION_MINOR 3
|
||||||
#define VERSION_PATCH 0
|
#define VERSION_PATCH 0
|
||||||
#define VERSION_BUILD 6459
|
#define VERSION_BUILD 6503
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="72" height="80" tilewidth="24" tileheight="24" infinite="0" nextlayerid="5" nextobjectid="6">
|
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="72" height="80" tilewidth="24" tileheight="24" infinite="0" nextlayerid="5" nextobjectid="7">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
||||||
<property name="Background Music" propertytype="BGM" value="foresty_boss"/>
|
<property name="Background Music" propertytype="BGM" value="foresty_boss"/>
|
||||||
@ -275,5 +275,6 @@
|
|||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="6" name="Boss Arena" type="BossArena" x="196" y="285" width="1339" height="1395"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="72" height="80" tilewidth="24" tileheight="24" infinite="0" nextlayerid="5" nextobjectid="6">
|
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="72" height="80" tilewidth="24" tileheight="24" infinite="0" nextlayerid="5" nextobjectid="9">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
||||||
<property name="Background Music" propertytype="BGM" value="foresty_boss"/>
|
<property name="Background Music" propertytype="BGM" value="foresty_boss"/>
|
||||||
@ -275,5 +275,7 @@
|
|||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="6" name="Boss Arena" type="BossArena" x="196" y="285" width="1339" height="1395"/>
|
||||||
|
<object id="7" x="29" y="444"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
@ -669,7 +669,7 @@
|
|||||||
<property name="Unlock Condition" propertytype="Level" value="BOSS_1"/>
|
<property name="Unlock Condition" propertytype="Level" value="BOSS_1"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="17" name="Stage VI" type="StagePlate" x="156.25" y="475.75" width="44" height="16">
|
<object id="17" name="Stage B-I" type="StagePlate" x="156.25" y="475.75" width="44" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Connection 2 - East" type="object" value="18"/>
|
<property name="Connection 2 - East" type="object" value="18"/>
|
||||||
<property name="Connection 3 - South" type="object" value="0"/>
|
<property name="Connection 3 - South" type="object" value="0"/>
|
||||||
@ -679,7 +679,7 @@
|
|||||||
<property name="Unlock Condition" propertytype="Level" value="CAMPAIGN_1_5"/>
|
<property name="Unlock Condition" propertytype="Level" value="CAMPAIGN_1_5"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="18" name="Boss I" type="StagePlate" x="192" y="516" width="32" height="24">
|
<object id="18" name="Boss B-I" type="StagePlate" x="192" y="516" width="32" height="24">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Connection 1 - North" type="object" value="0"/>
|
<property name="Connection 1 - North" type="object" value="0"/>
|
||||||
<property name="Map" propertytype="Level" value="BOSS_1_B"/>
|
<property name="Map" propertytype="Level" value="BOSS_1_B"/>
|
||||||
|
@ -381,7 +381,7 @@ Monsters
|
|||||||
DROP[2] = Bear Claw,30%,1,1
|
DROP[2] = Bear Claw,30%,1,1
|
||||||
|
|
||||||
Hurt Sound = Monster Hurt
|
Hurt Sound = Monster Hurt
|
||||||
Death Sound = Slime Dead
|
Death Sound = Ursule Dead
|
||||||
Walk Sound = Slime Walk
|
Walk Sound = Slime Walk
|
||||||
|
|
||||||
#Additional custom animations go down below. Start with ANIMATION[0] Order is:
|
#Additional custom animations go down below. Start with ANIMATION[0] Order is:
|
||||||
|
@ -95,19 +95,20 @@ BGM
|
|||||||
{
|
{
|
||||||
Track Name = Foresty Loop 1
|
Track Name = Foresty Loop 1
|
||||||
|
|
||||||
channel[0]=loop2/foresty1_1_loop1_bass.ogg
|
channel[0]=loop1/foresty1_1_loop1_bass.ogg
|
||||||
channel[1]=loop2/foresty1_1_loop1_drums.ogg
|
channel[1]=loop1/foresty1_1_loop1_drums.ogg
|
||||||
channel[2]=loop2/foresty1_1_loop1_piano 1.ogg
|
channel[2]=loop1/foresty1_1_loop1_flute.ogg
|
||||||
channel[3]=loop2/foresty1_1_loop1_piano 2.ogg
|
channel[3]=loop1/foresty1_1_loop1_piano 1.ogg
|
||||||
channel[4]=loop2/foresty1_1_loop1_staccato.ogg
|
channel[4]=loop1/foresty1_1_loop1_piano 2.ogg
|
||||||
channel[5]=loop2/foresty1_1_loop1_strings.ogg
|
channel[5]=loop1/foresty1_1_loop1_strings.ogg
|
||||||
|
channel[6]=loop1/foresty1_1_loop1_xtra perc.ogg
|
||||||
|
|
||||||
# Transition time between one phase to the next.
|
# Transition time between one phase to the next.
|
||||||
Fade Time = 2.0
|
Fade Time = 2.0
|
||||||
|
|
||||||
Events
|
Events
|
||||||
{
|
{
|
||||||
Default Volume = 0%,70%,0%,70%,70%,0%
|
Default Volume = 0%,70%,0%,0%,70%,70%,0%
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -144,6 +144,11 @@ Events
|
|||||||
File[1] = slime_walk2.ogg, 10%
|
File[1] = slime_walk2.ogg, 10%
|
||||||
File[2] = slime_walk3.ogg, 10%
|
File[2] = slime_walk3.ogg, 10%
|
||||||
}
|
}
|
||||||
|
Ursule Dead
|
||||||
|
{
|
||||||
|
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||||
|
File[0] = ursule_dead.ogg, 100%
|
||||||
|
}
|
||||||
Ursule Phase Transition
|
Ursule Phase Transition
|
||||||
{
|
{
|
||||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||||
|
@ -155,3 +155,6 @@ water_reflection_scale_factor = 0.05
|
|||||||
# The message displayed to the user about ID creation.
|
# The message displayed to the user about ID creation.
|
||||||
user_id_message = In order to save progress online, we ask that you provide a unique username to identify your save data with.
|
user_id_message = In order to save progress online, we ask that you provide a unique username to identify your save data with.
|
||||||
user_id_message2 = When loading a file, you will need this unique ID.
|
user_id_message2 = When loading a file, you will need this unique ID.
|
||||||
|
|
||||||
|
# How large the exit ring is for a boss when it's killed.
|
||||||
|
boss_spawn_ring_radius = 116
|
Binary file not shown.
BIN
Adventures in Lestoria/assets/sounds/ursule_dead.ogg
Normal file
BIN
Adventures in Lestoria/assets/sounds/ursule_dead.ogg
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user