Update Overworld Map with new stage plates. Updated stages with spawn zones and end zones. Cleaned up sound effects with extra noise. Updated some sound effects with more appropriate ones. Added sound effects for many events.

pull/29/head
sigonasr2 11 months ago
parent 0643393b9c
commit c7ea530484
  1. 30
      Adventures in Lestoria/AdventuresInLestoria.cpp
  2. 2
      Adventures in Lestoria/BuyItemWindow.cpp
  3. 6
      Adventures in Lestoria/CharacterMenuWindow.cpp
  4. 7
      Adventures in Lestoria/Item.cpp
  5. 2
      Adventures in Lestoria/ItemDrop.cpp
  6. 27
      Adventures in Lestoria/Monster.cpp
  7. 11
      Adventures in Lestoria/Monster.h
  8. 29
      Adventures in Lestoria/MonsterData.cpp
  9. 10
      Adventures in Lestoria/Player.cpp
  10. 2
      Adventures in Lestoria/Player.h
  11. 6
      Adventures in Lestoria/Ranger.cpp
  12. 2
      Adventures in Lestoria/SellItemWindow.cpp
  13. 6
      Adventures in Lestoria/SlimeKing.cpp
  14. 1
      Adventures in Lestoria/SoundEffect.cpp
  15. 2
      Adventures in Lestoria/Version.h
  16. 3
      Adventures in Lestoria/assets/Campaigns/1_3.tmx
  17. 3
      Adventures in Lestoria/assets/Campaigns/1_4.tmx
  18. 3
      Adventures in Lestoria/assets/Campaigns/1_5.tmx
  19. 4
      Adventures in Lestoria/assets/Campaigns/1_6.tmx
  20. 4
      Adventures in Lestoria/assets/Campaigns/1_7.tmx
  21. 4
      Adventures in Lestoria/assets/Campaigns/1_8.tmx
  22. 53
      Adventures in Lestoria/assets/Campaigns/World_Map.tmx
  23. 24
      Adventures in Lestoria/assets/config/Monsters.txt
  24. 3
      Adventures in Lestoria/assets/config/Player.txt
  25. 50
      Adventures in Lestoria/assets/config/audio/events.txt
  26. 12
      Adventures in Lestoria/assets/config/classes/Ranger.txt
  27. 3
      Adventures in Lestoria/assets/config/items/Accessories.txt
  28. 40
      Adventures in Lestoria/assets/config/items/Equipment.txt
  29. 3
      Adventures in Lestoria/assets/config/levels.txt
  30. BIN
      Adventures in Lestoria/assets/sounds/birds1.ogg
  31. BIN
      Adventures in Lestoria/assets/sounds/birds3.ogg
  32. BIN
      Adventures in Lestoria/assets/sounds/birds4.ogg
  33. BIN
      Adventures in Lestoria/assets/sounds/equip_ring.ogg
  34. BIN
      Adventures in Lestoria/assets/sounds/item_collect.ogg
  35. BIN
      Adventures in Lestoria/assets/sounds/monster_hurt.ogg
  36. BIN
      Adventures in Lestoria/assets/sounds/slime_dead.ogg
  37. 2
      Adventures in Lestoria/olcUTIL_DataFile.h

@ -317,6 +317,7 @@ void AiL::HandleUserInput(float fElapsedTime){
if(!Menu::stack.empty())return; //A window being opened means there's no user input allowed.
bool setIdleAnimation=true;
bool heldDownMovementKey=false; //Is true when a movement key has been held down.
if(GetKey(F1).bPressed){
ConsoleShow(F1);
}
@ -376,6 +377,7 @@ void AiL::HandleUserInput(float fElapsedTime){
player->UpdateWalkingAnimation(RIGHT);
}
setIdleAnimation=false;
heldDownMovementKey=true;
}
if(LeftHeld()){
player->SetX(player->GetX()-fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
@ -395,6 +397,7 @@ void AiL::HandleUserInput(float fElapsedTime){
}
}
setIdleAnimation=false;
heldDownMovementKey=true;
}
if(UpHeld()){
player->SetY(player->GetY()-fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
@ -406,6 +409,7 @@ void AiL::HandleUserInput(float fElapsedTime){
}
}
setIdleAnimation=false;
heldDownMovementKey=true;
}
if(DownHeld()){
player->SetY(player->GetY()+fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
@ -417,6 +421,7 @@ void AiL::HandleUserInput(float fElapsedTime){
}
}
setIdleAnimation=false;
heldDownMovementKey=true;
}
}
if(UpReleased()){
@ -484,6 +489,29 @@ void AiL::HandleUserInput(float fElapsedTime){
setIdleAnimation=false;
}
if(heldDownMovementKey){
player->footstepTimer+=GetElapsedTime();
if(player->footstepTimer>"Player.Footstep Timer"_F){
player->footstepTimer-="Player.Footstep Timer"_F;
bool inWater=true;
for(const LayerTag&layer:GetCurrentMap().LayerData){
int tileID=layer.tiles[player->GetY()/24][player->GetX()/24]-1;
if(tileID!=-1&&!IsReflectiveTile(GetTileSheet(GetCurrentLevel(),tileID),tileID)){
inWater=false;
break;
}
}
if(inWater){
SoundEffect::PlaySFX("Footstep - Wet");
}else{
SoundEffect::PlaySFX("Footstep");
}
}
}
if(setIdleAnimation){
switch(player->GetLastReleasedMovementKey()){
case UP:{
@ -1920,6 +1948,7 @@ void AiL::ChangePlayerClass(Class cl){
uint32_t currentLevelXP=player->currentLevelXP;
std::set<MenuComponent*>moneyListeners=Player::moneyListeners;
EntityStats previousStats=player->stats;
size_t cooldownSoundInstance=player->cooldownSoundInstance;
switch(cl){
case WARRIOR:{
player.reset(NEW Warrior(player.get()));
@ -1953,6 +1982,7 @@ void AiL::ChangePlayerClass(Class cl){
player->hpGrowthRate=float(DATA.GetProperty(player->GetClassName()+".HealthGrowthRate").GetReal());
player->atkGrowthRate=float(DATA.GetProperty(player->GetClassName()+".AtkGrowthRate").GetReal());
player->money=oldMoney;
player->cooldownSoundInstance=cooldownSoundInstance;
sig::Animation::SetupPlayerAnimations();
GetPlayer()->UpdateIdleAnimation(DOWN);
GetPlayer()->SetItem1UseFunc(itemAbility1);

@ -38,6 +38,7 @@ All rights reserved.
#include "Menu.h"
#include "MenuLabel.h"
#include "SoundEffect.h"
using A=Attribute;
@ -85,6 +86,7 @@ void Menu::InitializeBuyItemWindow(){
Merchant&merchant=Merchant::GetCurrentTravelingMerchant();
const std::string&item=Component<MenuLabel>(BUY_ITEM,"Item Purchase Header")->GetString(A::ITEM_NAME);
merchant.PurchaseItem(item,GetQuantity());
SoundEffect::PlaySFX("Buy Item");
Menu::CloseMenu();
return true;
})END;

@ -47,6 +47,7 @@ All rights reserved.
#include "Item.h"
#include "ScrollableWindowComponent.h"
#include "RowItemDisplay.h"
#include "SoundEffect.h"
INCLUDE_game
INCLUDE_GFX
@ -136,9 +137,9 @@ void Menu::InitializeCharacterMenuWindow(){
const static auto OppositeRingSlotDoesNotMatchCurrentEquip=[](RowItemDisplay*comp){
EquipSlot slot=EquipSlot(comp->I(Attribute::EQUIP_TYPE));
std::weak_ptr<Item>otherItem;
if(slot==EquipSlot::RING1)otherItem=Inventory::GetEquip(EquipSlot::RING2);
if(slot&EquipSlot::RING1)otherItem=Inventory::GetEquip(EquipSlot::RING2);
else
if(slot==EquipSlot::RING2)otherItem=Inventory::GetEquip(EquipSlot::RING1);
if(slot&EquipSlot::RING2)otherItem=Inventory::GetEquip(EquipSlot::RING1);
return ISBLANK(otherItem)||(&*comp->GetItem().lock()!=&*otherItem.lock());
};
@ -148,6 +149,7 @@ void Menu::InitializeCharacterMenuWindow(){
if(comp!=nullptr){
if(OppositeRingSlotDoesNotMatchCurrentEquip(comp)){ //If we find that the opposite ring slot is equipped to us, this would be an item swap or the exact same ring, therefore no stat calculations apply.
Inventory::EquipItem(comp->GetItem(),EquipSlot(comp->I(Attribute::EQUIP_TYPE)));
SoundEffect::PlaySFX(comp->GetItem().lock()->UseSound());
for(MenuComponent*button:((ScrollableWindowComponent*)data.parentComponent)->GetComponents()){
RowItemDisplay*comp=DYNAMIC_CAST<RowItemDisplay*>(button);
if(comp!=nullptr){

@ -44,6 +44,7 @@ All rights reserved.
#include "AttributableStat.h"
#include <numeric>
#include "util.h"
#include "SoundEffect.h"
INCLUDE_game
INCLUDE_DATA
@ -147,7 +148,7 @@ void ItemInfo::InitializeItems(){
if(keyName=="SellValue"){
sellValue=data[key][keyName].GetInt();
}else
if(keyName=="UseSound"){
if(keyName=="UseSound"||keyName=="Equip Sound"){
useSound=data[key][keyName].GetString();
}else{ //THis is a custom override modifier for a script. NO-OP
}
@ -853,6 +854,8 @@ void Item::EnhanceItem(uint8_t qty){
Inventory::RemoveItem(Inventory::GetItem(name)[0],amt);
}
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-consumedResources.GetCost());
SoundEffect::PlaySFX("Enhance Item");
}else{ //This is a craftable, so we have to give the player the item they crafted.
Inventory::AddItem(ActualName());
@ -862,6 +865,8 @@ void Item::EnhanceItem(uint8_t qty){
Inventory::RemoveItem(Inventory::GetItem(name)[0],amt);
}
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-consumedResources.GetCost());
SoundEffect::PlaySFX("Craft Item");
}
}
};

@ -38,6 +38,7 @@ All rights reserved.
#include "ItemDrop.h"
#include "olcUTIL_Geometry2D.h"
#include "AdventuresInLestoria.h"
#include "SoundEffect.h"
INCLUDE_game
INCLUDE_GFX
@ -136,6 +137,7 @@ void ItemDrop::UpdateDrops(float fElapsedTime){
if(drop.collected){
Inventory::AddItem(drop.GetItem()->Name(),1,true);
ItemOverlay::AddToItemOverlay(*drop.GetItem());
SoundEffect::PlaySFX("Collect Item");
return true;
}
return false;

@ -46,6 +46,7 @@ All rights reserved.
#include "util.h"
#include "MonsterAttribute.h"
#include "ItemDrop.h"
#include "SoundEffect.h"
INCLUDE_ANIMATION_DATA
INCLUDE_MONSTER_DATA
@ -73,6 +74,7 @@ Monster::Monster(vf2d pos,MonsterData data,bool upperLevel,bool bossMob):
stats.A("Attack")=data.GetAttack();
stats.A("Move Spd %")=data.GetMoveSpdMult();
randomFrameOffset=(util::random()%1000)/1000.f;
monsterWalkSoundTimer=util::random(1.f);
}
vf2d&Monster::GetPos(){
return pos;
@ -152,6 +154,8 @@ bool Monster::SetY(float y){
bool Monster::Update(float fElapsedTime){
lastHitTimer=std::max(0.f,lastHitTimer-fElapsedTime);
iframe_timer=std::max(0.f,iframe_timer-fElapsedTime);
monsterHurtSoundCooldown=std::max(0.f,monsterHurtSoundCooldown-fElapsedTime);
if(size!=targetSize){
if(size>targetSize){
size=std::max(targetSize,size-AiL::SIZE_CHANGE_SPEED*fElapsedTime);
@ -275,6 +279,11 @@ void Monster::Moved(){
upperLevel=false;
}
}
monsterWalkSoundTimer+=game->GetElapsedTime();
if(monsterWalkSoundTimer>1.f){
monsterWalkSoundTimer-=1.f;
SoundEffect::PlaySFX(GetWalkSound());
}
}
std::string Monster::GetDeathAnimationName(){
return MONSTER_DATA[name].GetDeathAnimation();
@ -316,14 +325,22 @@ bool Monster::Hurt(int damage,bool onUpperLevel,float z){
lastHitTimer=0.05f;
if(!IsAlive()){
OnDeath();
SoundEffect::PlaySFX(GetDeathSound());
}else{
hp=std::max(1,hp); //Make sure it stays alive if it's supposed to be alive...
if(monsterHurtSoundCooldown==0.f){
monsterHurtSoundCooldown=util::random(0.5f)+0.5f;
SoundEffect::PlaySFX(GetHurtSound());
}
}
if(game->InBossEncounter()){
game->BossDamageDealt(int(mod_dmg));
}
GetInt(Attribute::HITS_UNTIL_DEATH)=std::max(0,GetInt(Attribute::HITS_UNTIL_DEATH)-1);
iframe_timer=GetFloat(Attribute::IFRAME_TIME_UPON_HIT);
return true;
}
@ -488,4 +505,14 @@ ItemAttribute&Monster::Get(std::string_view attr){
const uint32_t MonsterData::GetXP()const{
return xp;
}
const EventName&Monster::GetHurtSound(){
return MONSTER_DATA[name].GetHurtSound();
}
const EventName&Monster::GetDeathSound(){
return MONSTER_DATA[name].GetDeathSound();
}
const EventName&Monster::GetWalkSound(){
return MONSTER_DATA[name].GetWalkSound();
}

@ -83,6 +83,9 @@ struct MonsterData{
std::string jumpAnimation="WARRIOR_IDLE_S";
std::string shootAnimation="WARRIOR_IDLE_S";
std::string deathAnimation="WARRIOR_IDLE_S";
EventName hurtSound="";
EventName deathSound="";
EventName walkSound="";
std::vector<MonsterDropData> dropData;
public:
MonsterData();
@ -98,6 +101,9 @@ struct MonsterData{
std::string GetJumpAnimation();
std::string GetShootAnimation();
std::string GetDeathAnimation();
const EventName&GetHurtSound();
const EventName&GetDeathSound();
const EventName&GetWalkSound();
std::vector<std::string>GetAnimations(){
return animations;
}
@ -159,6 +165,9 @@ public:
void SetStrategyDrawFunction(std::function<void(AiL*)>func);
std::function<void(AiL*)>strategyDraw=[](AiL*pge){};
const ItemAttributable&GetStats()const;
const EventName&GetHurtSound();
const EventName&GetDeathSound();
const EventName&GetWalkSound();
private:
std::string name;
vf2d pos;
@ -180,6 +189,8 @@ private:
Animate2D::AnimationState internal_animState;
float randomFrameOffset=0.f;
float deathTimer=0.f;
float monsterHurtSoundCooldown=0.f;
float monsterWalkSoundTimer;
std::vector<Buff>buffList;
std::string GetDeathAnimationName();
bool hasHitPlayer=false;

@ -71,6 +71,20 @@ void MonsterData::InitializeMonsterData(){
MonsterData::imgs[MonsterName]=NEW Renderable();
MonsterData::imgs[MonsterName]->Load("assets/monsters/"+MonsterName+".png");
EventName hurtSound="";
EventName deathSound="";
EventName walkSound="";
if(DATA["Monsters"][MonsterName].HasProperty("Hurt Sound")){
hurtSound=DATA["Monsters"][MonsterName]["Hurt Sound"].GetString();
}
if(DATA["Monsters"][MonsterName].HasProperty("Death Sound")){
deathSound=DATA["Monsters"][MonsterName]["Death Sound"].GetString();
}
if(DATA["Monsters"][MonsterName].HasProperty("Walk Sound")){
walkSound=DATA["Monsters"][MonsterName]["Walk Sound"].GetString();
}
for(int i=0;i<animations.size();i++){
std::string animationConfigName="";
std::string imgName="";
@ -157,6 +171,10 @@ void MonsterData::InitializeMonsterData(){
DATA["Monsters"][MonsterName]["CollisionDmg"].GetInt()
);
monster.hurtSound=hurtSound;
monster.deathSound=deathSound;
monster.walkSound=walkSound;
MONSTER_DATA[MonsterName]=monster;
}
}
@ -196,4 +214,15 @@ std::string MonsterData::GetDeathAnimation(){
}
const std::vector<MonsterDropData>&MonsterData::GetDropData(){
return dropData;
}
const EventName&MonsterData::GetHurtSound(){
return hurtSound;
}
const EventName&MonsterData::GetDeathSound(){
return deathSound;
}
const EventName&MonsterData::GetWalkSound(){
return walkSound;
}

@ -96,6 +96,7 @@ void Player::Initialize(){
SetBaseStat("Crit Dmg","Player.Crit Dmg"_F);
SetBaseStat("Health %",0);
SetBaseStat("HP6 Recovery %",0);
cooldownSoundInstance=Audio::Engine().LoadSound("spell_cast.ogg"_SFX);
}
bool Player::SetX(float x){
@ -272,6 +273,15 @@ void Player::Update(float fElapsedTime){
SetState(State::NORMAL);
}
}
if(state==State::CASTING){
if(!Audio::Engine().IsPlaying(cooldownSoundInstance)){
Audio::Engine().Play(cooldownSoundInstance,true);
}
}else{
Audio::Engine().Stop(cooldownSoundInstance);
}
while(manaTickTimer<=0){
manaTickTimer+=0.2f;
RestoreMana(1,true);

@ -308,6 +308,8 @@ protected:
float endZoneStandTime=0;
const float RAPID_FIRE_SHOOT_DELAY="Ranger.Ability 1.ArrowDelay"_F;
const int RAPID_FIRE_SHOOT_AMOUNT="Ranger.Ability 1.ArrowCount"_I;
float footstepTimer=0.f;
size_t cooldownSoundInstance=std::numeric_limits<size_t>::max();
};
#pragma region Warrior

@ -44,6 +44,7 @@ All rights reserved.
#include "BulletTypes.h"
#include "util.h"
#include "config.h"
#include "SoundEffect.h"
INCLUDE_MONSTER_LIST
INCLUDE_BULLET_LIST
@ -74,6 +75,7 @@ bool Ranger::AutoAttack(){
BULLET_LIST.push_back(std::make_unique<Arrow>(Arrow(GetPos(),extendedLine,vf2d{cos(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F,float(sin(angleToCursor)*"Ranger.Auto Attack.ArrowSpd"_F-PI/8*"Ranger.Auto Attack.ArrowSpd"_F)}+movementVelocity,"Ranger.Auto Attack.Radius"_F/100*12,int(GetAttack()*"Ranger.Auto Attack.DamageMult"_F),OnUpperLevel(),true)));
SetState(State::SHOOT_ARROW);
SetAnimationBasedOnTargetingDirection(angleToCursor);
SoundEffect::PlaySFX("Ranger.Auto Attack.Sound"_S);
return true;
}
@ -92,6 +94,7 @@ void Ranger::InitializeClassAbilities(){
float angleToCursor=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x);
p->SetAnimationBasedOnTargetingDirection(angleToCursor);
p->SetState(State::RETREAT);
SoundEffect::PlaySFX("Ranger.Right Click Ability.Sound"_S);
return true;
};
#pragma endregion
@ -103,6 +106,7 @@ void Ranger::InitializeClassAbilities(){
if("Ranger.Ability 1.IsAnimationLocked"_I){
p->SetState(State::ANIMATION_LOCK);
}
SoundEffect::PlaySFX("Ranger.Ability 1.Sound"_S);
return true;
};
#pragma endregion
@ -114,6 +118,7 @@ void Ranger::InitializeClassAbilities(){
p->SetAnimationBasedOnTargetingDirection(atan2(arrowVelocity.y,arrowVelocity.x));
game->SetupWorldShake("Ranger.Ability 2.WorldShakeTime"_F);
p->Knockback(-1.f*arrowVelocity.norm()*"Ranger.Ability 2.Knockback"_F);
SoundEffect::PlaySFX("Ranger.Ability 2.Sound"_S);
return true;
};
#pragma endregion
@ -136,6 +141,7 @@ void Ranger::InitializeClassAbilities(){
BULLET_LIST.push_back(std::make_unique<Arrow>(Arrow(p->GetPos(),extendedLine,vf2d{cos(newAngle)*"Ranger.Ability 3.ArrowSpd"_F,float(sin(newAngle)*"Ranger.Ability 3.ArrowSpd"_F-PI/8*"Ranger.Ability 3.ArrowSpd"_F)}+p->movementVelocity,12*"Ranger.Ability 3.ArrowRadius"_F/100,int(p->GetAttack()*"Ranger.Ability 3.DamageMult"_F),p->OnUpperLevel(),true)));
}
p->SetAnimationBasedOnTargetingDirection(shootingAngle);
SoundEffect::PlaySFX("Ranger.Ability 3.Sound"_S);
return true;
};
#pragma endregion

@ -38,6 +38,7 @@ All rights reserved.
#include "Menu.h"
#include "ItemMenuLabel.h"
#include "SoundEffect.h"
using A=Attribute;
@ -84,6 +85,7 @@ void Menu::InitializeSellItemWindow(){
sellItemWindow->ADD("Sell Button",MenuComponent)({{sellItemWindow->size.x/2+18,70},{64,12}},"Sell",[&](MenuFuncData data){
Merchant&merchant=Merchant::GetCurrentTravelingMerchant();
merchant.SellItem(Component<ItemMenuLabel>(SELL_ITEM,"Item Sell Header")->GetItem(),GetQuantity());
SoundEffect::PlaySFX("Sell Item");
Menu::CloseMenu();
return true;
})END;

@ -44,6 +44,7 @@ All rights reserved.
#include "Effect.h"
#include "FallingDebris.h"
#include "MonsterAttribute.h"
#include "SoundEffect.h"
INCLUDE_game
INCLUDE_BULLET_LIST
@ -68,12 +69,14 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
float angle=((2*PI)/bulletCount)*i+angleOffset;
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
}
SoundEffect::PlaySFX("Slime King Shoot");
};
const auto Landed=[&ShootBulletRing,&m](int currentPhase){
if(currentPhase==1){
ShootBulletRing(m.F(A::SHOOT_RING_OFFSET));
}
SoundEffect::PlaySFX("Slime King Land");
};
const auto TransitionPhase=[&](int newPhase){
@ -288,6 +291,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
float angle=(i-(bulletCount/2))*util::degToRad(ConfigFloat("Phase2.ShootAngleSpread"))+initialAngle;
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
}
SoundEffect::PlaySFX("Slime King Shoot");
}
if(m.I(A::PATTERN_REPEAT_COUNT)>ConfigInt("Phase2.ShootCount")){
m.I(A::PATTERN_REPEAT_COUNT)=0;
@ -317,6 +321,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
float angle=(i-(bulletCount/2))*util::degToRad(ConfigFloat("Phase3.ShootAngleSpread"))+initialAngle;
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
}
SoundEffect::PlaySFX("Slime King Shoot");
}else
if(m.I(A::PATTERN_REPEAT_COUNT)>=4){
m.F(A::RECOVERY_TIME)=ConfigFloat("Phase3.PhaseRecoveryTime");
@ -346,6 +351,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
float spreadAngle=util::degToRad(ConfigFloat("Phase4.RandomOffsetAngle"));
bulletAngle+=util::random(spreadAngle*2)-spreadAngle;
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(bulletAngle),sin(bulletAngle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
SoundEffect::PlaySFX("Slime King Shoot");
}else
if(m.I(A::PATTERN_REPEAT_COUNT)==5){
m.I(A::PATTERN_REPEAT_COUNT)++;

@ -63,6 +63,7 @@ void SoundEffect::Initialize(){
}
void SoundEffect::PlaySFX(const std::string_view eventName){
if(eventName.length()==0)return;
auto itr=SOUND_EFFECTS.equal_range(std::string(eventName));
size_t soundCount=std::distance(itr.first,itr.second);
size_t soundEffectChoice=util::random()%soundCount;

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
#define VERSION_BUILD 5476
#define VERSION_BUILD 5498
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="240" height="120" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="17">
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="240" height="120" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="18">
<properties>
<property name="Level Type" propertytype="LevelType" value="Dungeon"/>
</properties>
@ -545,5 +545,6 @@
<object id="16" name="Spawn 14" type="SpawnGroup" x="4966" y="1993" width="368" height="350">
<ellipse/>
</object>
<object id="17" name="Player Spawn" type="PlayerSpawnLocation" x="360" y="1464" width="24" height="24"/>
</objectgroup>
</map>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="200" height="120" tilewidth="24" tileheight="24" infinite="0" nextlayerid="9" nextobjectid="22">
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="200" height="120" tilewidth="24" tileheight="24" infinite="0" nextlayerid="9" nextobjectid="23">
<properties>
<property name="Level Type" propertytype="LevelType" value="Dungeon"/>
</properties>
@ -436,5 +436,6 @@
<object id="21" name="Spawn 19" type="SpawnGroup" x="3493.94" y="781.818" width="369.697" height="345.455">
<ellipse/>
</object>
<object id="22" name="Player Spawn" type="PlayerSpawnLocation" x="3696" y="600" width="24" height="24"/>
</objectgroup>
</map>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="200" height="250" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="29">
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="200" height="250" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="30">
<properties>
<property name="Level Type" propertytype="LevelType" value="Dungeon"/>
</properties>
@ -1105,5 +1105,6 @@
<object id="28" name="Spawn 10" type="SpawnGroup" x="304" y="2524" width="376" height="376">
<ellipse/>
</object>
<object id="29" name="Player Spawn" type="PlayerSpawnLocation" x="1704" y="5448" width="24" height="24"/>
</objectgroup>
</map>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="250" height="175" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="29">
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="250" height="175" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="31">
<tileset firstgid="1" source="../maps/Decorations_c1_No_Shadow24x24.tsx"/>
<tileset firstgid="1621" source="../maps/Tilesheet_No_Shadow24x24.tsx"/>
<layer id="2" name="Layer 1" width="250" height="175">
@ -624,5 +624,7 @@
<object id="28" name="Spawn 26" type="SpawnGroup" x="5003" y="1489" width="358" height="358">
<ellipse/>
</object>
<object id="29" name="End Zone" type="EndZone" x="5856" y="1608" width="120" height="120"/>
<object id="30" name="Player Spawn" type="PlayerSpawnLocation" x="888" y="3432" width="24" height="24"/>
</objectgroup>
</map>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="225" height="150" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="22">
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="225" height="150" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="24">
<tileset firstgid="1" source="../maps/Decorations_c1_No_Shadow24x24.tsx"/>
<tileset firstgid="1621" source="../maps/Tilesheet_No_Shadow24x24.tsx"/>
<tileset firstgid="4533" source="../maps/24x24_Waterfall.tsx"/>
@ -677,5 +677,7 @@
<object id="21" name="Spawn 19" type="SpawnGroup" x="4638" y="2588" width="360" height="388">
<ellipse/>
</object>
<object id="22" name="Player Spawn" type="PlayerSpawnLocation" x="1776" y="288" width="24" height="24"/>
<object id="23" name="End Zone" type="EndZone" x="5016" y="2718" width="120" height="120"/>
</objectgroup>
</map>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="250" height="125" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="24">
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="250" height="125" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="26">
<tileset firstgid="1" source="../maps/Tilesheet_No_Shadow24x24.tsx"/>
<tileset firstgid="2913" source="../maps/Decorations_c1_No_Shadow24x24.tsx"/>
<layer id="2" name="Layer 1" width="250" height="125">
@ -459,5 +459,7 @@
<object id="23" name="Spawn 23" type="SpawnGroup" x="5420.09" y="1327.76" width="359.818" height="348.485">
<ellipse/>
</object>
<object id="24" name="End Zone" type="EndZone" x="5832" y="1440" width="120" height="120"/>
<object id="25" name="Player Spawn" type="PlayerSpawnLocation" x="360" y="1488" width="24" height="24"/>
</objectgroup>
</map>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="left-down" width="250" height="177" tilewidth="4" tileheight="4" infinite="0" nextlayerid="5" nextobjectid="12">
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="left-down" width="250" height="177" tilewidth="4" tileheight="4" infinite="0" nextlayerid="5" nextobjectid="17">
<properties>
<property name="Level Type" propertytype="LevelType" value="World Map"/>
<property name="Optimize" type="bool" value="true"/>
@ -553,7 +553,7 @@
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11035,11036,11037,11038,11039,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
<objectgroup id="4" name="Object Layer 1">
<objectgroup id="4" name="Stage Plates">
<object id="2" name="Temp Player Spawn" type="PlayerSpawnLocation" x="200" y="325" width="20" height="20"/>
<object id="3" name="Stage I-I" type="StagePlate" x="252" y="496" width="44" height="16">
<properties>
@ -607,7 +607,7 @@
</object>
<object id="9" name="Stage IV" type="StagePlate" x="172" y="580" width="44" height="16">
<properties>
<property name="Connection 1" type="object" value="0"/>
<property name="Connection 1" type="object" value="12"/>
<property name="Connection 2" type="object" value="0"/>
<property name="Map" propertytype="Level" value="CAMPAIGN_1_4"/>
<property name="Type" propertytype="StageType" value="DUNGEON"/>
@ -616,11 +616,56 @@
</object>
<object id="11" name="Boss I" type="StagePlate" x="156" y="644" width="32" height="24">
<properties>
<property name="Connection 1" type="object" value="0"/>
<property name="Connection 1" type="object" value="16"/>
<property name="Map" propertytype="Level" value="BOSS_1"/>
<property name="Type" propertytype="StageType" value="BOSS"/>
<property name="Unlock Condition" propertytype="Level" value="CAMPAIGN_1_8"/>
</properties>
</object>
<object id="12" name="Stage V" type="StagePlate" x="112" y="532" width="44" height="16">
<properties>
<property name="Connection 1" type="object" value="13"/>
<property name="Connection 2" type="object" value="0"/>
<property name="Map" propertytype="Level" value="CAMPAIGN_1_5"/>
<property name="Type" propertytype="StageType" value="DUNGEON"/>
<property name="Unlock Condition" propertytype="Level" value="CAMPAIGN_1_4"/>
</properties>
</object>
<object id="13" name="Stage VI" type="StagePlate" x="60" y="484" width="44" height="16">
<properties>
<property name="Connection 1" type="object" value="14"/>
<property name="Connection 2" type="object" value="0"/>
<property name="Map" propertytype="Level" value="CAMPAIGN_1_6"/>
<property name="Type" propertytype="StageType" value="DUNGEON"/>
<property name="Unlock Condition" propertytype="Level" value="CAMPAIGN_1_5"/>
</properties>
</object>
<object id="14" name="Stage VII" type="StagePlate" x="36" y="556" width="44" height="16">
<properties>
<property name="Connection 1" type="object" value="15"/>
<property name="Connection 2" type="object" value="0"/>
<property name="Map" propertytype="Level" value="CAMPAIGN_1_7"/>
<property name="Type" propertytype="StageType" value="DUNGEON"/>
<property name="Unlock Condition" propertytype="Level" value="CAMPAIGN_1_6"/>
</properties>
</object>
<object id="15" name="Stage VIII" type="StagePlate" x="72" y="612" width="44" height="16">
<properties>
<property name="Connection 1" type="object" value="11"/>
<property name="Connection 2" type="object" value="0"/>
<property name="Map" propertytype="Level" value="CAMPAIGN_1_8"/>
<property name="Type" propertytype="StageType" value="DUNGEON"/>
<property name="Unlock Condition" propertytype="Level" value="CAMPAIGN_1_7"/>
</properties>
</object>
<object id="16" name="Story III" type="StagePlate" x="160" y="612" width="20" height="24">
<properties>
<property name="Connection 1" type="object" value="0"/>
<property name="Connection 2" type="object" value="0"/>
<property name="Map" propertytype="Level" value="STORY_1_3"/>
<property name="Type" propertytype="StageType" value="STORY"/>
<property name="Unlock Condition" propertytype="Level" value="BOSS_1"/>
</properties>
</object>
</objectgroup>
</map>

@ -29,6 +29,10 @@ Monsters
DROP[1] = Minor Health Potion,5%,1,1
DROP[2] = Berries,5%,1,1
Hurt Sound = Monster Hurt
Death Sound = Slime Dead
Walk Sound = Slime Walk
#Additional custom animations go down below. Start with ANIMATION[0]. Order is:
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
#ANIMATION[0] = 6, 0.1, Repeat
@ -56,6 +60,10 @@ Monsters
ShootAnimation = 10, 0.1, Repeat
DeathAnimation = 10, 0.1, OneShot
Hurt Sound = Monster Hurt
Death Sound = Slime Dead
Walk Sound = Slime Walk
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
DROP[0] = Blue Slime Remains,65%,1,2
DROP[1] = Minor Health Potion,5%,1,1
@ -87,6 +95,10 @@ Monsters
ShootAnimation = 10, 0.1, OneShot
DeathAnimation = 10, 0.1, OneShot
Hurt Sound = Monster Hurt
Death Sound = Slime Dead
Walk Sound = Slime Walk
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
DROP[0] = Red Slime Remains,65%,1,2
DROP[1] = Minor Health Potion,5%,1,1
@ -118,6 +130,10 @@ Monsters
ShootAnimation = 10, 0.1, OneShot
DeathAnimation = 10, 0.1, OneShot
Hurt Sound = Monster Hurt
Death Sound = Slime Dead
Walk Sound = Slime Walk
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
DROP[0] = Berries,5%,1,1
@ -147,6 +163,10 @@ Monsters
ShootAnimation = 5, 0.1, OneShot
DeathAnimation = 5, 0.2, OneShot
Hurt Sound = Monster Hurt
Death Sound = Slime Dead
# Walk Sound = Slime Walk # DOES NOT WALK!
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
DROP[0] = Bandages,30%,1,1
DROP[1] = Berries,5%,1,1
@ -179,6 +199,10 @@ Monsters
ShootAnimation = 10, 0.1, OneShot
DeathAnimation = 10, 0.1, OneShot
Hurt Sound = Monster Hurt
Death Sound = Slime Dead
Walk Sound = Slime Walk
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
DROP[0] = Berries,5%,1,1

@ -26,6 +26,9 @@ Player
# How long the player must stand in the end zone before leaving the level.
End Zone Wait Time = 5.0
# How long between each footstep.
Footstep Timer = 0.4
# Each attack will have _N,_E,_S,_W appended to them once read in-game.
PLAYER_ANIMATION[0] = WARRIOR_WALK
PLAYER_ANIMATION[1] = WARRIOR_IDLE

@ -19,8 +19,8 @@ Events
Equip Armor
{
# Specify file names, followed by volume %
File[0] = equip.ogg, 100%
File[1] = equip2.ogg, 100%
File[0] = equip.ogg, 60%
File[1] = equip2.ogg, 60%
}
Equip Accessory
{
@ -30,7 +30,7 @@ Events
Footstep
{
# Specify file names, followed by volume %
File[0] = footsteps.ogg, 100%
File[0] = footsteps.ogg, 90%
}
Footstep - Wet
{
@ -40,38 +40,43 @@ Events
Buy Item
{
# Specify file names, followed by volume %
File[0] = item_buy.ogg, 100%
File[0] = item_buy.ogg, 70%
}
Sell Item
{
# Specify file names, followed by volume %
File[0] = item_sell.ogg, 100%
File[0] = item_sell.ogg, 80%
}
Craft Item
{
# Specify file names, followed by volume %
File[0] = item_craft.ogg, 100%
File[0] = item_craft.ogg, 70%
}
Enhance Item
{
# Specify file names, followed by volume %
File[0] = item_enhance.ogg, 100%
}
Collect Item
{
# Specify file names, followed by volume %
File[0] = item_collect.ogg, 40%
}
Monster Hurt
{
# Specify file names, followed by volume %
File[0] = monster_hurt.ogg, 100%
File[0] = monster_hurt.ogg, 40%
}
Ranger Auto Attack
{
# Specify file names, followed by volume %
File[0] = ranger_auto1.ogg, 100%
File[1] = ranger_auto2.ogg, 100%
File[0] = ranger_auto1.ogg, 50%
File[1] = ranger_auto2.ogg, 50%
}
Ranger Backstep
Ranger Retreat
{
# Specify file names, followed by volume %
File[0] = ranger_backstep.ogg, 100%
File[0] = ranger_backstep.ogg, 90%
}
Ranger Multishot
{
@ -86,22 +91,18 @@ Events
Ranger Charged Shot
{
# Specify file names, followed by volume %
File[0] = ranger_charged_shot.ogg, 100%
}
Ranger Multishot
{
# Specify file names, followed by volume %
File[0] = ranger_multishot.ogg, 100%
File[0] = ranger_charged_shot.ogg, 70%
}
Slime Dead
{
# Specify file names, followed by volume %
File[0] = slime_dead.ogg, 100%
File[0] = slime_dead.ogg, 60%
File[1] = slime_dead2.ogg, 60%
}
Monster Dead
{
# Specify file names, followed by volume %
File[0] = slime_dead2.ogg, 100%
File[0] = slime_dead2.ogg, 60%
}
Slime King Land
{
@ -122,14 +123,9 @@ Events
Slime Walk
{
# Specify file names, followed by volume %
File[0] = slime_walk.ogg, 100%
File[1] = slime_walk2.ogg, 100%
File[2] = slime_walk3.ogg, 100%
}
Spell Cast
{
# Specify file names, followed by volume %
File[0] = spell_cast.ogg, 100%
File[0] = slime_walk.ogg, 10%
File[1] = slime_walk2.ogg, 10%
File[2] = slime_walk3.ogg, 10%
}
Warrior Auto Attack
{

@ -21,7 +21,8 @@ Ranger
CancelCast = 0
ArrowSpd = 250
Sound = Ranger Auto Attack
}
Right Click Ability
{
@ -47,6 +48,8 @@ Ranger
RetreatTime = 0.2
# The distance the retreat moves the Ranger.
RetreatDistance = 250
Sound = Ranger Retreat
}
Ability 1
{
@ -81,6 +84,8 @@ Ranger
# Hitbox radius of the arrows
ArrowRadius = 100
Sound = Ranger Rapid Fire
}
Ability 2
{
@ -113,6 +118,8 @@ Ranger
# How long the world shakes upon using this ability.
WorldShakeTime = 0.3
Sound = Ranger Charged Shot
}
Ability 3
{
@ -145,6 +152,7 @@ Ranger
# Hitbox radius of the arrows
ArrowRadius = 100
Sound = Ranger Multishot
}
}

@ -11,6 +11,7 @@ Equipment
MaxStats = 20,4,4,3
SellValue = 90
Equip Sound = Equip Accessory
}
Ring of the Bear
{
@ -22,5 +23,7 @@ Equipment
MinStats = 4,4,1
MaxStats = 10,10,3
SellValue = 75
Equip Sound = Equip Accessory
}
}

@ -21,6 +21,8 @@ Equipment
StatValues[9] = 10,7,4
StatValues[10] = 11,8,4
Equip Sound = Equip Armor
Crafting
{
Level[1]
@ -106,6 +108,8 @@ Equipment
StatValues[8] = 13,5,4
StatValues[9] = 14,6,4
StatValues[10] = 15,7,4
Equip Sound = Equip Armor
Crafting
{
@ -192,6 +196,8 @@ Equipment
StatValues[8] = 12,5,5
StatValues[9] = 13,5,6
StatValues[10] = 14,5,7
Equip Sound = Equip Armor
Crafting
{
@ -278,6 +284,8 @@ Equipment
StatValues[8] = 7,4,7
StatValues[9] = 8,4,7
StatValues[10] = 8,4,8
Equip Sound = Equip Armor
Crafting
{
@ -364,6 +372,8 @@ Equipment
StatValues[8] = 8,5,4
StatValues[9] = 9,5,4
StatValues[10] = 9,5,5
Equip Sound = Equip Armor
Crafting
{
@ -450,6 +460,8 @@ Equipment
StatValues[8] = 17,11,5
StatValues[9] = 18,12,5
StatValues[10] = 20,12,5
Equip Sound = Equip Armor
Crafting
{
@ -536,6 +548,8 @@ Equipment
StatValues[8] = 21,8,5
StatValues[9] = 23,9,5
StatValues[10] = 25,10,5
Equip Sound = Equip Armor
Crafting
{
@ -622,6 +636,8 @@ Equipment
StatValues[8] = 18,7,8
StatValues[9] = 20,7,9
StatValues[10] = 22,8,10
Equip Sound = Equip Armor
Crafting
{
@ -708,6 +724,8 @@ Equipment
StatValues[8] = 9,5,11
StatValues[9] = 10,5,12
StatValues[10] = 11,5,12
Equip Sound = Equip Armor
Crafting
{
@ -794,6 +812,8 @@ Equipment
StatValues[8] = 10,7,6
StatValues[9] = 11,7,7
StatValues[10] = 12,8,8
Equip Sound = Equip Armor
Crafting
{
@ -880,6 +900,8 @@ Equipment
StatValues[8] = 33,13,6
StatValues[9] = 35,14,6
StatValues[10] = 40,14,6
Equip Sound = Equip Armor
Crafting
{
@ -966,6 +988,8 @@ Equipment
StatValues[8] = 45,11,6
StatValues[9] = 51,12,6
StatValues[10] = 57,12,6
Equip Sound = Equip Armor
Crafting
{
@ -1052,6 +1076,8 @@ Equipment
StatValues[8] = 34,9,11
StatValues[9] = 38,9,12
StatValues[10] = 42,10,12
Equip Sound = Equip Armor
Crafting
{
@ -1138,6 +1164,8 @@ Equipment
StatValues[8] = 13,6,13
StatValues[9] = 14,6,14
StatValues[10] = 15,6,14
Equip Sound = Equip Armor
Crafting
{
@ -1224,6 +1252,8 @@ Equipment
StatValues[8] = 14,9,9
StatValues[9] = 15,9,9
StatValues[10] = 16,10,10
Equip Sound = Equip Armor
Crafting
{
@ -1310,6 +1340,8 @@ Equipment
StatValues[8] = 46,17,7
StatValues[9] = 51,17,7
StatValues[10] = 53,19,7
Equip Sound = Equip Armor
Crafting
{
@ -1396,6 +1428,8 @@ Equipment
StatValues[8] = 67,13,7
StatValues[9] = 70,14,7
StatValues[10] = 72,14,7
Equip Sound = Equip Armor
Crafting
{
@ -1483,6 +1517,8 @@ Equipment
StatValues[8] = 53,11,13
StatValues[9] = 57,11,14
StatValues[10] = 61,12,14
Equip Sound = Equip Armor
Crafting
{
@ -1569,6 +1605,8 @@ Equipment
StatValues[8] = 17,7,17
StatValues[9] = 18,7,17
StatValues[10] = 19,7,19
Equip Sound = Equip Armor
Crafting
{
@ -1655,6 +1693,8 @@ Equipment
StatValues[8] = 18,11,11
StatValues[9] = 19,11,11
StatValues[10] = 21,12,12
Equip Sound = Equip Armor
Crafting
{

@ -11,4 +11,7 @@ Levels
CAMPAIGN_1_3 = 1_3.tmx
CAMPAIGN_1_4 = 1_4.tmx
CAMPAIGN_1_5 = 1_5.tmx
CAMPAIGN_1_6 = 1_6.tmx
CAMPAIGN_1_7 = 1_7.tmx
CAMPAIGN_1_8 = 1_8.tmx
}

@ -366,6 +366,8 @@ namespace olc::utils
// first assignment, trim any whitespace from ends
sPropName = line.substr(0, x);
trim(sPropName);
auto&top=stkPath.top().get();
if(stkPath.top().get().HasProperty(sPropName))ERR(std::format("WARNING! Duplicate key found! Key {} already exists! Duplicate line: {}",sPropName,line));
// Extract the property value, which is all characters after
// the first assignment operator, trim any whitespace from ends

Loading…
Cancel
Save