|
|
|
|
#pragma region License
|
|
|
|
|
/*
|
|
|
|
|
License (OLC-3)
|
|
|
|
|
~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
|
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
|
are permitted provided that the following conditions are met:
|
|
|
|
|
|
|
|
|
|
1. Redistributions or derivations of source code must retain the above copyright
|
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
|
|
|
|
|
|
2. Redistributions or derivative works in binary form must reproduce the above
|
|
|
|
|
copyright notice. This list of conditions and the following disclaimer must be
|
|
|
|
|
reproduced in the documentation and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
|
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
|
|
|
|
be used to endorse or promote products derived from this software without specific
|
|
|
|
|
prior written permission.
|
|
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
|
|
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
|
|
|
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
|
|
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
|
|
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
|
SUCH DAMAGE.
|
|
|
|
|
|
|
|
|
|
Portions of this software are copyright <EFBFBD> 2024 The FreeType
|
|
|
|
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
|
|
|
|
All rights reserved.
|
|
|
|
|
*/
|
|
|
|
|
#pragma endregion
|
|
|
|
|
#include "AdventuresInLestoria.h"
|
|
|
|
|
#include "DEFINES.h"
|
|
|
|
|
#include "Monster.h"
|
|
|
|
|
#include "MonsterStrategyHelpers.h"
|
|
|
|
|
#include "BulletTypes.h"
|
|
|
|
|
#include "util.h"
|
|
|
|
|
|
|
|
|
|
INCLUDE_game
|
|
|
|
|
|
|
|
|
|
using A=Attribute;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Every 2 seconds after completing an attack do one of the following attacks:
|
|
|
|
|
Casts a Stone Pillar on the location of the Player: radius 350. Hits with 3 seconds delay. Becomes an solid object (Player colision) and decays after 5 seconds again.
|
|
|
|
|
If the Stone pillar would hit the Stone Elemental it will move out of its range.
|
|
|
|
|
Shoot a Stone (bullet) in the direction of the target.
|
|
|
|
|
The Stone gets created in form of a Cone and tracks the player movement without moving for the first second.
|
|
|
|
|
Once it locks it doesnt move for another second. then it starts flying towards the player with 3x the normal Bullet speed.
|
|
|
|
|
Dive under earth and show up 1 second later in a random location 400-700 away from player. while emerging shoot a ring of bullets (0.5x Attack)
|
|
|
|
|
(maybe emerge with 200 away from anything with colision to avoid the Elemental getting stuck? Other solutions for that are welcome aswell)
|
|
|
|
|
if range to player > 1200 always use 3rd attack
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void Monster::STRATEGY::STONE_ELEMENTAL(Monster&m,float fElapsedTime,std::string strategy){
|
|
|
|
|
enum PhaseName{
|
|
|
|
|
WAITING,
|
|
|
|
|
STONE_PILLAR_CAST,
|
|
|
|
|
STONE_PILLAR_ATTACK,
|
|
|
|
|
SHOOT_STONE_CAST,
|
|
|
|
|
SHOOT_STONE_ATTACK,
|
|
|
|
|
DIVE_UNDERGROUND_DIG,
|
|
|
|
|
DIVE_UNDERGROUND_SURFACE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
switch(m.phase){
|
|
|
|
|
case WAITING:{
|
|
|
|
|
m.F(A::ATTACK_COOLDOWN)+=fElapsedTime;
|
|
|
|
|
|
|
|
|
|
//float distToPlayer=util::distance(m.GetPos(),game->GetPlayer()->GetPos());
|
|
|
|
|
//if(distToPlayer>=ConfigPixels("Auto Dive Range"))m.phase=DIVE_UNDERGROUND_DIG;
|
|
|
|
|
|
|
|
|
|
if(m.F(A::ATTACK_COOLDOWN)>=ConfigFloat("Attack Wait Time")){
|
|
|
|
|
switch(util::random()%1){
|
|
|
|
|
case 0:{
|
|
|
|
|
m.PerformAnimation("STONE PILLAR CAST");
|
|
|
|
|
m.phase=STONE_PILLAR_CAST;
|
|
|
|
|
m.F(A::CASTING_TIMER)=ConfigFloat("Stone Pillar Cast Time");
|
|
|
|
|
m.V(A::LOCKON_POS)=game->GetPlayer()->GetPos();
|
|
|
|
|
game->AddEffect(std::make_unique<Effect>(m.V(A::LOCKON_POS),ConfigFloat("Stone Pillar Cast Time"),"range_indicator.png",m.OnUpperLevel(),vf2d{1.f,1.f}*MONSTER_DATA.at("Stone Pillar").GetSizeMult(),0.3f,vf2d{},ConfigPixel("Stone Pillar Spell Circle Color"),util::random(2*PI),util::degToRad(ConfigFloat("Stone Pillar Spell Circle Rotation Spd"))),true);
|
|
|
|
|
game->AddEffect(std::make_unique<Effect>(m.V(A::LOCKON_POS),ConfigFloat("Stone Pillar Cast Time"),"spell_insignia.png",m.OnUpperLevel(),vf2d{1.f,1.f}*MONSTER_DATA.at("Stone Pillar").GetSizeMult()*0.75f,0.3f,vf2d{},ConfigPixel("Stone Pillar Spell Insignia Color"),util::random(2*PI),util::degToRad(ConfigFloat("Stone Pillar Spell Insignia Rotation Spd"))),true);
|
|
|
|
|
}break;
|
|
|
|
|
case 1:{
|
|
|
|
|
m.PerformAnimation("ROCK TOSS CAST");
|
|
|
|
|
m.phase=SHOOT_STONE_CAST;
|
|
|
|
|
m.F(A::CASTING_TIMER)=ConfigFloat("Rock Toss Track Time")+ConfigFloat("Rock Toss Wait Time");
|
|
|
|
|
}break;
|
|
|
|
|
case 2:{
|
|
|
|
|
m.PerformAnimation("BURROW UNDEGROUND");
|
|
|
|
|
m.phase=DIVE_UNDERGROUND_DIG;
|
|
|
|
|
m.F(A::CASTING_TIMER)=ConfigFloat("Burrow Wait Time");
|
|
|
|
|
}break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}break;
|
|
|
|
|
case STONE_PILLAR_CAST:{
|
|
|
|
|
m.F(A::CASTING_TIMER)-=fElapsedTime;
|
|
|
|
|
if(m.F(A::CASTING_TIMER)<=0.f){
|
|
|
|
|
m.phase=STONE_PILLAR_ATTACK;
|
|
|
|
|
}
|
|
|
|
|
}break;
|
|
|
|
|
case SHOOT_STONE_CAST:{
|
|
|
|
|
m.F(A::CASTING_TIMER)-=fElapsedTime;
|
|
|
|
|
if(m.F(A::CASTING_TIMER)<=0.f){
|
|
|
|
|
m.phase=SHOOT_STONE_ATTACK;
|
|
|
|
|
}
|
|
|
|
|
}break;
|
|
|
|
|
case DIVE_UNDERGROUND_DIG:{
|
|
|
|
|
m.F(A::CASTING_TIMER)-=fElapsedTime;
|
|
|
|
|
if(m.F(A::CASTING_TIMER)<=0.f){
|
|
|
|
|
m.phase=DIVE_UNDERGROUND_SURFACE;
|
|
|
|
|
}
|
|
|
|
|
}break;
|
|
|
|
|
case STONE_PILLAR_ATTACK:{
|
|
|
|
|
|
|
|
|
|
}break;
|
|
|
|
|
case SHOOT_STONE_ATTACK:{
|
|
|
|
|
|
|
|
|
|
}break;
|
|
|
|
|
case DIVE_UNDERGROUND_SURFACE:{
|
|
|
|
|
|
|
|
|
|
}break;
|
|
|
|
|
}
|
|
|
|
|
}
|