Implemented Concussive Trap enchant.
This commit is contained in:
parent
9005771f77
commit
60175a20d2
@ -974,5 +974,42 @@ namespace EnchantTests
|
||||
}
|
||||
Assert::AreEqual(size_t(1),newMonster.GetBuffs(BuffType::SPECIAL_MARK).size(),L"A special mark should spawned with the enchant.");
|
||||
}
|
||||
TEST_METHOD(ConcussiveTrapEnchantCheck){
|
||||
testKey->bHeld=true; //Force the key to be held down for testing purposes.
|
||||
game->ChangePlayerClass(TRAPPER);
|
||||
player=game->GetPlayer();
|
||||
player->SetPos({120,120});
|
||||
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
||||
game->SetElapsedTime(0.5f);
|
||||
game->OnUserUpdate(0.5f);
|
||||
Assert::AreEqual(size_t(1),BULLET_LIST.size(),L"An Explosive Trap now exists");
|
||||
Monster&newMonster{game->SpawnMonster({},MONSTER_DATA["TestName"])};
|
||||
game->OnUserUpdate(0.f);
|
||||
BULLET_LIST.front()->MonsterHit(newMonster,newMonster.GetMarkStacks());
|
||||
Assert::AreEqual(929,newMonster.GetHealth(),L"Monster takes 71 damage from an Explosive Trap normally.");
|
||||
game->SetElapsedTime(5.5f);
|
||||
game->OnUserUpdate(5.5f);
|
||||
game->SetElapsedTime(5.5f);
|
||||
game->OnUserUpdate(5.5f);
|
||||
game->SetElapsedTime(0.5f);
|
||||
game->OnUserUpdate(0.5f);
|
||||
Assert::AreEqual(size_t(0),BULLET_LIST.size(),L"An Explosive Trap is gone.");
|
||||
|
||||
std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)};
|
||||
Inventory::EquipItem(nullRing,EquipSlot::RING1);
|
||||
nullRing.lock()->EnchantItem("Concussive Trap");
|
||||
player->GetAbility3().charges=1;
|
||||
player->CheckAndPerformAbility(player->GetAbility3(),testKeyboardInput);
|
||||
game->SetElapsedTime(0.5f);
|
||||
game->OnUserUpdate(0.5f);
|
||||
Assert::AreEqual(size_t(1),BULLET_LIST.size(),L"An Explosive Trap now exists");
|
||||
game->SetElapsedTime(5.5f);
|
||||
game->OnUserUpdate(5.5f);
|
||||
Assert::AreEqual(size_t(1),BULLET_LIST.size(),L"An Explosive Trap still exists (in the process of detonating a few times)");
|
||||
Assert::AreEqual(721,newMonster.GetHealth(),L"Monster takes 104 + 104 damage from Concussive Trap bonus (Collision+Collateral Explosion).");
|
||||
game->SetElapsedTime(5.5f);
|
||||
game->OnUserUpdate(5.5f);
|
||||
Assert::AreEqual(size_t(0),BULLET_LIST.size(),L"Explosive Trap detonates later.");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ namespace ItemTests
|
||||
GameState::Initialize();
|
||||
GameState::STATE=GameState::states.at(States::State::GAME_RUN);
|
||||
|
||||
testGame->ResetLevelStates();
|
||||
#pragma region Setup a fake test map and test monster
|
||||
game->MAP_DATA["CAMPAIGN_1_1"];
|
||||
ItemDrop::ClearDrops();
|
||||
|
@ -82,6 +82,7 @@ namespace MonsterTests
|
||||
|
||||
GameState::Initialize();
|
||||
GameState::STATE=GameState::states.at(States::State::GAME_RUN);
|
||||
testGame->ResetLevelStates();
|
||||
|
||||
#pragma region Setup a fake test map
|
||||
game->MAP_DATA["CAMPAIGN_1_1"];
|
||||
|
@ -88,6 +88,7 @@ namespace PlayerTests
|
||||
MonsterData testMonsterData{"TestName","Test Monster",1000,10,5,{MonsterDropData{"Health Potion",100.f,1,1}},200.f};
|
||||
MONSTER_DATA["TestName"]=testMonsterData;
|
||||
#pragma endregion
|
||||
testGame->ResetLevelStates();
|
||||
|
||||
player=testGame->GetPlayer();
|
||||
//Setup key "0" as a test input
|
||||
|
@ -2387,55 +2387,7 @@ void AiL::_PrepareLevel(MapName map,MusicChange changeMusic){
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
bossIndicatorPos.reset();
|
||||
SPAWNER_LIST.clear();
|
||||
SPAWNER_CONTROLLER={};
|
||||
foregroundTileGroups.clear();
|
||||
upperForegroundTileGroups.clear();
|
||||
MONSTER_LIST.clear();
|
||||
BULLET_LIST.clear();
|
||||
DAMAGENUMBER_LIST.clear();
|
||||
hudOverlay.Reset();
|
||||
backgroundEffects.clear();
|
||||
foregroundEffects.clear();
|
||||
lockOnTargets.clear();
|
||||
lockOnSpecialTargets.clear();
|
||||
ItemDrop::drops.clear();
|
||||
GameEvent::events.clear();
|
||||
Audio::SetBGMPitch(1.f);
|
||||
RepeatingSoundEffect::StopAllSounds();
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Audio::muted=true;
|
||||
Audio::UpdateBGMVolume();
|
||||
#endif
|
||||
zoomAdjustSpeed="Default Zoom Adjust Speed"_F;
|
||||
targetZoom=1.f;
|
||||
game->view.SetZoom(0.95f,game->view.WorldToScreen(game->camera.GetViewPosition()));
|
||||
worldColor=WHITE;
|
||||
worldColorFunc=[&](vi2d pos){return game->worldColor;};
|
||||
levelTime=0;
|
||||
bossName="";
|
||||
bossDisplayTimer=0.f;
|
||||
worldShakeTime=0.f;
|
||||
encounterDuration=0;
|
||||
totalDamageDealt=0;
|
||||
encounterStarted=false;
|
||||
totalBossEncounterMobs=0;
|
||||
SetWindSpeed({});
|
||||
Inventory::ResetLoadoutItemsUsed();
|
||||
Input::StopVibration();
|
||||
|
||||
Input::SetLightbar({255,0,255});
|
||||
GetPlayer()->hp=GetPlayer()->GetMaxHealth();
|
||||
GetPlayer()->mana=GetPlayer()->GetMaxMana();
|
||||
GetPlayer()->SetState(State::NORMAL);
|
||||
GetPlayer()->GetCastInfo()={};
|
||||
GetPlayer()->ResetAccumulatedXP();
|
||||
GetPlayer()->_SetIframes(0.f);
|
||||
GetPlayer()->SetInvisible(false);
|
||||
GetPlayer()->ResetVelocity();
|
||||
GetPlayer()->RemoveAllBuffs();
|
||||
GetPlayer()->ResetTimers();
|
||||
ResetLevelStates();
|
||||
|
||||
STEAMINPUT( //This is kind of a hack to refresh the in-game controls handle and button icons if for some reason it's not setup correctly.
|
||||
Input::LoadSteamButtonIcons();
|
||||
@ -4619,3 +4571,55 @@ void AiL::InitializeCamera(){
|
||||
camera.SetWorldBoundary({0,0},GetCurrentMap().MapData.MapSize*GetCurrentMap().MapData.TileSize);
|
||||
camera.EnableWorldBoundary(false);
|
||||
}
|
||||
|
||||
void AiL::ResetLevelStates(){
|
||||
bossIndicatorPos.reset();
|
||||
SPAWNER_LIST.clear();
|
||||
SPAWNER_CONTROLLER={};
|
||||
foregroundTileGroups.clear();
|
||||
upperForegroundTileGroups.clear();
|
||||
MONSTER_LIST.clear();
|
||||
BULLET_LIST.clear();
|
||||
DAMAGENUMBER_LIST.clear();
|
||||
hudOverlay.Reset();
|
||||
backgroundEffects.clear();
|
||||
foregroundEffects.clear();
|
||||
lockOnTargets.clear();
|
||||
lockOnSpecialTargets.clear();
|
||||
ItemDrop::drops.clear();
|
||||
GameEvent::events.clear();
|
||||
Audio::SetBGMPitch(1.f);
|
||||
RepeatingSoundEffect::StopAllSounds();
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Audio::muted=true;
|
||||
Audio::UpdateBGMVolume();
|
||||
#endif
|
||||
zoomAdjustSpeed="Default Zoom Adjust Speed"_F;
|
||||
targetZoom=1.f;
|
||||
game->view.SetZoom(0.95f,game->view.WorldToScreen(game->camera.GetViewPosition()));
|
||||
worldColor=WHITE;
|
||||
worldColorFunc=[&](vi2d pos){return game->worldColor;};
|
||||
levelTime=0;
|
||||
bossName="";
|
||||
bossDisplayTimer=0.f;
|
||||
worldShakeTime=0.f;
|
||||
encounterDuration=0;
|
||||
totalDamageDealt=0;
|
||||
encounterStarted=false;
|
||||
totalBossEncounterMobs=0;
|
||||
SetWindSpeed({});
|
||||
Inventory::ResetLoadoutItemsUsed();
|
||||
Input::StopVibration();
|
||||
|
||||
Input::SetLightbar({255,0,255});
|
||||
GetPlayer()->hp=GetPlayer()->GetMaxHealth();
|
||||
GetPlayer()->mana=GetPlayer()->GetMaxMana();
|
||||
GetPlayer()->SetState(State::NORMAL);
|
||||
GetPlayer()->GetCastInfo()={};
|
||||
GetPlayer()->ResetAccumulatedXP();
|
||||
GetPlayer()->_SetIframes(0.f);
|
||||
GetPlayer()->SetInvisible(false);
|
||||
GetPlayer()->ResetVelocity();
|
||||
GetPlayer()->RemoveAllBuffs();
|
||||
GetPlayer()->ResetTimers();
|
||||
}
|
@ -394,6 +394,8 @@ public:
|
||||
void _SetCurrentLevel(const MapName map); //NOTE: This will modify the currentLevel variable without triggering anything else in-game, this will normally mess up the state in the game. Ideally this is only used when initializing a test level.
|
||||
void InitializeCamera();
|
||||
|
||||
void ResetLevelStates();
|
||||
|
||||
std::vector<Effect*>GetForegroundEffects()const;
|
||||
std::vector<Effect*>GetBackgroundEffects()const;
|
||||
std::vector<Effect*>GetAllEffects()const; //Foreground and background effects in one vector.
|
||||
|
@ -61,6 +61,7 @@ enum BuffType{
|
||||
DAMAGE_AMPLIFICATION, //Multiplies all incoming damage by this amount.
|
||||
LETHAL_TEMPO,
|
||||
BURNING_ARROW_BURN,
|
||||
SWORD_ENCHANTMENT,
|
||||
};
|
||||
enum class BuffRestorationType{
|
||||
ONE_OFF, //This is used as a hack fix for the RestoreDuringCast Item script since they require us to restore 1 tick immediately. Over time buffs do not apply a tick immediately.
|
||||
|
@ -318,6 +318,8 @@ private:
|
||||
float automaticDetonationTime{};
|
||||
float activationWaitTime{};
|
||||
float lastBeepTime{};
|
||||
int explosionCount{1};
|
||||
float rearmTime{};
|
||||
uint8_t beepCount{1U};
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,7 @@ INCLUDE_ANIMATION_DATA
|
||||
INCLUDE_game
|
||||
|
||||
ExplosiveTrap::ExplosiveTrap(vf2d pos,float radius,float explosionRadius,float automaticDetonationTime,int damage,float fadeinTime,float fadeoutTime,float activationWaitTime,bool upperLevel,bool hitsMultiple,float lifetime,bool friendly,Pixel col,vf2d scale)
|
||||
:activationWaitTime(activationWaitTime),automaticDetonationTime(automaticDetonationTime),activationRadius(radius),explosionRadius(explosionRadius),Bullet(pos,{},0.f,damage,"Ability Icons/explosive_trap.png",upperLevel,hitsMultiple,lifetime,false,friendly,col,scale,0.f,"Trap Hit"){
|
||||
:activationWaitTime(activationWaitTime),automaticDetonationTime(automaticDetonationTime),activationRadius(radius),explosionRadius(explosionRadius),explosionCount(game->GetPlayer()->HasEnchant("Concussive Trap")?"Concussive Trap"_ENC["TRAP EXPLODE COUNT"]:1),Bullet(pos,{},0.f,damage,"Ability Icons/explosive_trap.png",upperLevel,hitsMultiple,INFINITE,false,friendly,col,scale,0.f,"Trap Hit"){
|
||||
fadeInTime=fadeinTime;
|
||||
animation.AddState("explosive_trap.png",ANIMATION_DATA["explosive_trap.png"]);
|
||||
if(!friendly)ERR("WARNING! Trying to use unimplemented enemy version of the Explosive Trap Bullet!");
|
||||
@ -58,7 +58,10 @@ void ExplosiveTrap::Update(float fElapsedTime){
|
||||
|
||||
if(IsDeactivated())return;
|
||||
|
||||
if(!trapActivated){
|
||||
if(rearmTime>0.f){
|
||||
rearmTime-=fElapsedTime;
|
||||
if(rearmTime<=0.f)Detonate();
|
||||
}else if(!trapActivated){
|
||||
activationWaitTime-=fElapsedTime;
|
||||
if(activationWaitTime<=0.f){
|
||||
radius=activationRadius;
|
||||
@ -89,8 +92,7 @@ BulletDestroyState ExplosiveTrap::PlayerHit(Player*player){
|
||||
}
|
||||
|
||||
void ExplosiveTrap::Detonate(){
|
||||
fadeOutTime=0.5f;
|
||||
const HurtList list{game->HurtNotHit(pos,"Trapper.Ability 3.Explosion Radius"_F/100.f*24,damage,hitList,OnUpperLevel(),GetZ(),HurtType::MONSTER,HurtFlag::PLAYER_ABILITY)};
|
||||
const HurtList list{game->Hurt(pos,"Trapper.Ability 3.Explosion Radius"_F/100.f*24,damage,OnUpperLevel(),GetZ(),HurtType::MONSTER,HurtFlag::PLAYER_ABILITY)};
|
||||
for(const auto&[targetPtr,wasHit]:list){
|
||||
if(wasHit){
|
||||
std::get<Monster*>(targetPtr)->ApplyMark("Trapper.Ability 3.Explosion Mark Stack Time"_F,"Trapper.Ability 3.Explosion Mark Stack Increase"_I);
|
||||
@ -103,7 +105,13 @@ void ExplosiveTrap::Detonate(){
|
||||
explodeEffect->scaleSpd={0.125f,0.125f};
|
||||
game->AddEffect(std::move(explodeEffect));
|
||||
SoundEffect::PlaySFX("Explosion",pos);
|
||||
explosionCount--;
|
||||
if(explosionCount>0)rearmTime=0.6f;
|
||||
else{
|
||||
fadeOutTime=0.5f;
|
||||
Deactivate();
|
||||
lifetime=0.f;
|
||||
}
|
||||
}
|
||||
|
||||
BulletDestroyState ExplosiveTrap::MonsterHit(Monster&monster,const uint8_t markStacksBeforeHit){
|
||||
|
@ -335,6 +335,7 @@ float Player::GetSizeMult()const{
|
||||
float Player::GetAttackRange(){
|
||||
float finalAttackRange{base_attack_range};
|
||||
if(HasEnchant("Adrenaline Stim")&&GetBuffs(BuffType::ADRENALINE_RUSH).size()>0)finalAttackRange+=base_attack_range*"Adrenaline Stim"_ENC["ATTACK RANGE INCREASE PCT"]/100.f;
|
||||
if(GetBuffs(BuffType::SWORD_ENCHANTMENT).size()>0)finalAttackRange+=base_attack_range*"Sword Enchantment"_ENC["AUTO RANGE INCREASE"]/100.f;
|
||||
finalAttackRange*=GetSizeMult();
|
||||
return finalAttackRange;
|
||||
}
|
||||
|
@ -126,7 +126,9 @@ void Trapper::InitializeClassAbilities(){
|
||||
#pragma region Trapper Ability 3 (Explosive Trap)
|
||||
Trapper::ability3.action=
|
||||
[](Player*p,vf2d pos={}){
|
||||
CreateBullet(ExplosiveTrap)(p->GetPos(),"Trapper.Ability 3.Trap Radius"_I,"Trapper.Ability 3.Explosion Radius"_F/100.f*24,"Trapper.Ability 3.Trap Auto Detonate Time"_F,"Trapper.Ability 3.DamageMult"_F*p->GetAttack(),0.2f,0.5f,"Trapper.Ability 3.Trap Activation Time"_F,p->OnUpperLevel(),false,INFINITE,true,WHITE,{1.f,1.f})EndBullet;
|
||||
float trapDamage{"Trapper.Ability 3.DamageMult"_F*p->GetAttack()};
|
||||
if(p->HasEnchant("Concussive Trap"))trapDamage+=p->GetAttack()*"Concussive Trap"_ENC["ADDITIONAL EXPLOSION DAMAGE"]/100.f;
|
||||
CreateBullet(ExplosiveTrap)(p->GetPos(),"Trapper.Ability 3.Trap Radius"_I,"Trapper.Ability 3.Explosion Radius"_F/100.f*24,"Trapper.Ability 3.Trap Auto Detonate Time"_F,trapDamage,0.2f,0.5f,"Trapper.Ability 3.Trap Activation Time"_F,p->OnUpperLevel(),false,INFINITE,true,WHITE,{1.f,1.f})EndBullet;
|
||||
SoundEffect::PlaySFX("Place Down Trap",p->GetPos());
|
||||
p->SetAnimationBasedOnTargetingDirection("SETTRAP",p->GetFacingDirection());
|
||||
return true;
|
||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 3
|
||||
#define VERSION_BUILD 11039
|
||||
#define VERSION_BUILD 11048
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
@ -168,6 +168,7 @@ void Warrior::InitializeClassAbilities(){
|
||||
}
|
||||
BULLET_LIST.push_back(std::make_unique<Bullet>(p->GetPos(),bulletVel,"Warrior.Ability 3.Radius"_F,p->GetAttack()*"Warrior.Ability 3.DamageMult"_F,"sonicslash.png",p->upperLevel,true,"Warrior.Ability 3.Lifetime"_F,true,true,WHITE,vf2d{"Warrior.Ability 3.Radius"_F/30,"Warrior.Ability 3.Radius"_F/30}));
|
||||
game->SetupWorldShake("Warrior.Ability 3.ShakeTime"_F);
|
||||
if(p->HasEnchant("Sword Enchantment"))p->AddBuff(BuffType::SWORD_ENCHANTMENT,"Sword Enchantment"_ENC["INCREASE DURATION"],1);
|
||||
SoundEffect::PlaySFX("Warrior Sonic Slash",SoundEffect::CENTERED);
|
||||
return true;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user