diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 2832db02..d1741f57 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -216,7 +216,7 @@ bool Crawler::OnUserCreate(){ Inventory::AddItem("Wooden Sword"); Inventory::AddItem("Laser Sword"); Inventory::AddItem("Shell Sword"); - Inventory::AddItem("Ring of the Slime King"); + Inventory::AddItem("Ring of the Slime King",4); LoadLevel(LEVEL_NAMES["starting_map"_S]); ChangePlayerClass(WARRIOR); diff --git a/Crawler/Item.cpp b/Crawler/Item.cpp index 1efe989d..e6621921 100644 --- a/Crawler/Item.cpp +++ b/Crawler/Item.cpp @@ -380,11 +380,11 @@ Item::Item(uint32_t amt,IT item,uint8_t enhancementLevel) void Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){ if(!ITEM_DATA.count(it))ERR("Item "<newItem=(*_inventory.insert({it,std::make_shared(amt,it)})).second; - newItem->RandomizeStats(); if(ITEM_DATA[it].IsEquippable()){ //Do not stack equips! for(uint32_t i=0;inewItem=(*_inventory.insert({it,std::make_shared(amt,it)})).second; + newItem->RandomizeStats(); InsertIntoSortedInv(newItem); } goto SkipAddingStackableItem; @@ -392,7 +392,7 @@ void Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){ else //There are two places to manipulate items in (Both the sorted inventory and the actual inventory) if(!_inventory.count(it)){ - InsertIntoSortedInv(newItem); + InsertIntoSortedInv((*_inventory.insert({it,std::make_shared(amt,it)})).second); }else{ auto inventory=_inventory.equal_range(it); if(std::accumulate(inventory.first,inventory.second,0, @@ -564,7 +564,11 @@ const bool Item::IsEquippable()const{ } const std::string Item::Description(CompactText compact)const{ std::string description=it->Description(); - if(IsArmor()||IsWeapon()){ + if(IsEquippable()){ + if(HasRandomizedStats()){ + description+='\n'; + description+=randomizedStats.GetStatsString(); + } description+='\n'; description+=GetStats().GetStatsString(compact); if(ItemSet()){ @@ -791,7 +795,7 @@ void ItemInfo::InitializeSets(){ } } -const Stats&ItemInfo::GetStats(int enhancementLevel)const{ +const Stats ItemInfo::GetStats(int enhancementLevel)const{ if(enhancement.size()<=enhancementLevel){ return {}; } @@ -1074,4 +1078,8 @@ Stats ItemInfo::RandomizeStats(){ } } return randomRolls; +} + +const bool Item::HasRandomizedStats()const{ + return randomizedStats.size()>0; } \ No newline at end of file diff --git a/Crawler/Item.h b/Crawler/Item.h index d374d085..2db60942 100644 --- a/Crawler/Item.h +++ b/Crawler/Item.h @@ -102,6 +102,9 @@ public: auto end()const{ return attributes.end(); } + const size_t size()const{ + return attributes.size(); + } const std::string GetStatsString(CompactText compact=NON_COMPACT)const; }; @@ -203,6 +206,7 @@ public: const bool CanBePurchased()const; const Stats&RandomStats()const; void RandomizeStats(); + const bool HasRandomizedStats()const; const EnhancementInfo&GetEnhancementInfo()const; //Use ISBLANK macro instead!! This should not be called directly!! static bool IsBlank(std::shared_ptritem); @@ -305,7 +309,7 @@ public: For the useFunc, return true if the item can be used, false otherwise. */ const ItemScript&OnUseAction()const; - const Stats&GetStats(int enhancementLevel)const; + const Stats GetStats(int enhancementLevel)const; const float CastTime()const; const float CooldownTime()const; const EquipSlot Slot()const; diff --git a/Crawler/LightningBolt.cpp b/Crawler/LightningBolt.cpp index c27c17a3..b1f10de6 100644 --- a/Crawler/LightningBolt.cpp +++ b/Crawler/LightningBolt.cpp @@ -56,7 +56,7 @@ void LightningBolt::Update(float fElapsedTime){ if(lastParticleSpawn==0){ lastParticleSpawn="Wizard.Ability 2.ParticleFrequency"_F; uint8_t brightness=uint8_t("Wizard.Ability 2.ParticleColorRange"_FRange); - switch(rand()%4){ + switch(util::random()%4){ case 0:{ game->AddEffect(std::make_unique(pos+vf2d{"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange,"Wizard.Ability 2.ParticleSpawnRadiusRange"_FRange},"Wizard.Ability 2.ParticleLifetimeRange"_FRange,"lightning_bolt_part1.png",upperLevel,"Wizard.Ability 2.ParticleSizeRange"_FRange,"Wizard.Ability 2.ParticleFadeoutTime"_F,vel*"Wizard.Ability 2.ParticleSpeedMultRange"_FRange,Pixel{brightness,brightness,brightness})); }break; diff --git a/Crawler/LightningBoltEmitter.cpp b/Crawler/LightningBoltEmitter.cpp index b6353f3d..85d94c11 100644 --- a/Crawler/LightningBoltEmitter.cpp +++ b/Crawler/LightningBoltEmitter.cpp @@ -56,7 +56,7 @@ void LightningBoltEmitter::DrawLightningBolt(){ const int MAX_ITERATIONS=100; geom2d::linelineToTarget=geom2d::line(startPos,endPos); float targetAngle=atan2(lineToTarget.vector().y,lineToTarget.vector().x); - float targetDist=lineToTarget.length()*util::random(0.5); + float targetDist=lineToTarget.length()*util::random(0.5f); targetAngle+=util::random((PI/2))-PI/4; geom2d::linelightningLine=geom2d::line(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist}); game->AddEffect(std::make_unique(lightningLine.upoint(0),0,"chain_lightning.png",upperLevel,vf2d{lightningLine.length(),0.2f},0.2f,vf2d{},WHITE,targetAngle,0,true)); @@ -65,7 +65,7 @@ void LightningBoltEmitter::DrawLightningBolt(){ while(iterations(currentPos,endPos).length()>1){ geom2d::linelineToTarget=geom2d::line(currentPos,endPos); float targetAngle=atan2(lineToTarget.vector().y,lineToTarget.vector().x); - float targetDist=lineToTarget.length()*util::random(0.5); + float targetDist=lineToTarget.length()*util::random(0.5f); targetAngle+=util::random((PI/2))-PI/4; geom2d::linelightningLine=geom2d::line(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist}); game->AddEffect(std::make_unique(lightningLine.upoint(0),0,"chain_lightning.png",upperLevel,vf2d{lightningLine.length(),0.2f},0.2f,vf2d{},WHITE,targetAngle,0,true)); diff --git a/Crawler/Merchant.cpp b/Crawler/Merchant.cpp index a9e9d6fe..34856c91 100644 --- a/Crawler/Merchant.cpp +++ b/Crawler/Merchant.cpp @@ -39,6 +39,7 @@ All rights reserved. #include "Menu.h" #include "Merchant.h" #include "Crawler.h" +#include "util.h" INCLUDE_game INCLUDE_ITEM_CATEGORIES @@ -50,7 +51,7 @@ MerchantFunctionPrimingData Merchant::sellFunctionPrimed("CanSellItem()"); Merchant Merchant::travelingMerchant; const Merchant&Merchant::GetRandomMerchant(Chapter chapter){ - const Merchant&newMerchant=merchants[chapter][rand()%(merchants[chapter].size()-1)]; + const Merchant&newMerchant=merchants[chapter][util::random()%(merchants[chapter].size()-1)]; return newMerchant; } diff --git a/Crawler/Monster.cpp b/Crawler/Monster.cpp index 9d86e091..ddb8a36a 100644 --- a/Crawler/Monster.cpp +++ b/Crawler/Monster.cpp @@ -72,7 +72,7 @@ Monster::Monster(vf2d pos,MonsterData data,bool upperLevel,bool bossMob): stats.A("Health")=data.GetHealth(); stats.A("Attack")=data.GetAttack(); stats.A("Move Spd %")=data.GetMoveSpdMult(); - randomFrameOffset=(rand()%1000)/1000.f; + randomFrameOffset=(util::random()%1000)/1000.f; } vf2d&Monster::GetPos(){ return pos; diff --git a/Crawler/SlimeKing.cpp b/Crawler/SlimeKing.cpp index 4463221a..f2d2e601 100644 --- a/Crawler/SlimeKing.cpp +++ b/Crawler/SlimeKing.cpp @@ -256,7 +256,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat m.F(A::SHOOT_RING_DELAY)=ConfigFloat("Phase1.ShootRingDelay"); ShootBulletRing(m.F(A::SHOOT_RING_OFFSET)); m.F(A::SHOOT_RING_TIMER)=ConfigFloat("Phase1.ShootRepeatTime"); - m.B(A::SHOOT_RING_RIGHT)=bool(rand()%2); + m.B(A::SHOOT_RING_RIGHT)=bool(util::random()%2); m.I(A::PATTERN_REPEAT_COUNT)++; } if(m.I(A::SHOOT_RING_COUNTER)>0){ diff --git a/Crawler/Version.h b/Crawler/Version.h index 55ac3e84..60a678fd 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 1 -#define VERSION_BUILD 5122 +#define VERSION_BUILD 5140 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/util.cpp b/Crawler/util.cpp index be087022..ba6e5352 100644 --- a/Crawler/util.cpp +++ b/Crawler/util.cpp @@ -39,8 +39,17 @@ All rights reserved. #include "olcPixelGameEngine.h" #include "olcPGEX_TTF.h" +std::random_device rd; +std::mt19937 rng(rd()); + float util::random(float range){ - return float(rand())/RAND_MAX*range; + static std::uniform_real_distributiondistrib(0,1); + return distrib(rng)*range; +} + +int util::random(){ + static std::uniform_int_distributiondistrib(0,32767); + return distrib(rng); } vf2d util::pointTo(vf2d posFrom,vf2d posTo){ diff --git a/Crawler/util.h b/Crawler/util.h index b22ae02e..9ef8ccf7 100644 --- a/Crawler/util.h +++ b/Crawler/util.h @@ -38,10 +38,13 @@ All rights reserved. #pragma once #include #include "olcUTIL_Geometry2D.h" +#include namespace olc::util{ //Returns 0-range (as a float). float random(float range); + //Returns 0-32767 (as an int). + int random(); //Returns a normalized vector pointing from posFrom towards posTo. vf2d pointTo(vf2d posFrom,vf2d posTo); //Returns the angle (in radians) pointing from posFrom towards posTo.