Implemented Spider
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 7m30s

This commit is contained in:
AMay 2026-04-07 14:56:47 -05:00
parent ac2f0290d7
commit 8e3e6d6cd4
22 changed files with 171 additions and 9 deletions

1
.gitignore vendored
View File

@ -430,4 +430,3 @@ desktop.ini
tools
/dotnet-tools.json
/Adventures in Lestoria Tests/EffectTests.cpp

View File

@ -1094,6 +1094,7 @@
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="Spider.cpp" />
<ClCompile Include="ThunderOrb.cpp" />
<ClCompile Include="TileGroup.cpp" />
<ClCompile Include="Menu.cpp" />
@ -1400,6 +1401,7 @@
<Text Include="Chapter_2_Monsters.txt" />
<Text Include="Chapter_3_FinalBoss.txt" />
<Text Include="Chapter_3_Monsters.txt" />
<Text Include="Chapter_4_Boss.txt" />
<Text Include="Chapter_4_Monsters.txt" />
<Text Include="characters.txt" />
<Text Include="ConsoleCommands.txt" />

View File

@ -1379,6 +1379,9 @@
<ClCompile Include="ExpandingRing.cpp">
<Filter>Source Files\Effects</Filter>
</ClCompile>
<ClCompile Include="Spider.cpp">
<Filter>Source Files\Monster Strategies</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />
@ -1664,6 +1667,7 @@
<Text Include="Chapter_4_Monsters.txt">
<Filter>Documentation\Mechanics</Filter>
</Text>
<Text Include="Chapter_4_Boss.txt" />
</ItemGroup>
<ItemGroup>
<Image Include="assets\heart.ico">

View File

@ -820,7 +820,7 @@ void AiL::UpdateEffects(float fElapsedTime){
enum class AliveState:bool{ALIVE,DEAD};
AliveState previousAliveState{!effect.effect?AliveState::DEAD:AliveState::ALIVE};
if(previousAliveState==AliveState::DEAD)return;
if(!std::visit(EffectOverloads{},*effect.effect,std::variant<float>{fElapsedTime})){effect.effect.reset();}
if(!std::visit(EffectOverloads{},*effect.effect,std::variant<float>{fElapsedTime}))effect.effect.reset();
AliveState newAliveState{!effect.effect?AliveState::DEAD:AliveState::ALIVE};
if(previousAliveState==AliveState::ALIVE&&newAliveState==AliveState::DEAD)effCount--;
[[unlikely]]if(previousAliveState==AliveState::DEAD&&newAliveState==AliveState::ALIVE)ERR(std::format("WARNING! Effect in slot {} has resurrected! THIS SHOULD NOT BE HAPPENING!",effectSlot));

View File

@ -0,0 +1,12 @@
Bonus Boss:
You fight against 3 "Shadows" of Heroes. which is basically a combination for Warrior + Thief, Archer + Trapper and Wizard + Witch
Endboss:
I want to have an empowered version for The Skelett Berserker, Skelett Archer and Captain
The Lich itself just appears casts a spell and you need to interrupt him. Once the 3 Empowered Minions are defeated he basically gives up.
didnt bringt the Lich down to paper yet. For the Shdows i want to give it a reread before i send it to you.
This short explanation is just for the Commision. Not sure if you want to commission the bosses aswell already

View File

@ -111,7 +111,7 @@ Like Dagger Goblin behaviour + while attacking the snake dashes 300 range forwar
Spider
HP: 500
ATK: 51
Movespeed:
Movespeed:
Size: 70%
Exp: 34

View File

@ -558,6 +558,8 @@ void Monster::Draw()const{
&&(OnUpperLevel()!=game->GetPlayer()->OnUpperLevel()||abs(GetZ()-game->GetPlayer()->GetZ())>1))blendColAlpha=blendCol.a*0.62f;
else if(IsSolid()&&solidFadeTimer>0.f)blendColAlpha=uint8_t(util::lerp(blendCol.a,uint8_t(255-TileGroup::FADE_AMT),solidFadeTimer/TileGroup::FADE_TIME));
blendColAlpha=uint8_t(blendColAlpha*(transparency/255.f));
blendCol.a=blendColAlpha;
const float finalSpriteRot=HasFourWaySprites()?0.f:spriteRot; //Prevent 4-way sprites from being rotated.
@ -1812,4 +1814,12 @@ Buff&Monster::GetOrAddBuff(BuffType buffType,std::pair<BuffDuration,BuffIntensit
const Monster::MonsterStrategy&Monster::GetStrategy()const{
return stringToStrategyMap.at(GetStrategyName());
}
void Monster::SetTransparency(uint8_t alpha){
this->transparency=alpha;
}
uint8_t Monster::GetTransparency()const{
return transparency;
}

View File

@ -127,8 +127,15 @@ public:
SKELETON_CAPTAIN,
SKELETON_CAPTAIN_FLAG,
SKELETON_MAGE,
SPIDER,
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
END_ENUM //THIS SHOULD ALWAYS BE THE LAST ITEM
};
struct STRATEGY{
@ -182,6 +189,7 @@ public:
static void SKELETON_CAPTAIN(Monster&m,float fElapsedTime,const std::string&strategy);
static void SKELETON_CAPTAIN_FLAG(Monster&m,float fElapsedTime,const std::string&strategy);
static void SKELETON_MAGE(Monster&m,float fElapsedTime,const std::string&strategy);
static void SPIDER(Monster&m,float fElapsedTime,const std::string&strategy);
};
struct StrategyFunction{
std::string name;
@ -358,6 +366,8 @@ public:
const std::vector<MonsterAbilityData>&GetAbilities()const;
const float GetMPRecovery()const;
void CastAbility(const MonsterAbilityData&data,const vf2d pos={});
void SetTransparency(uint8_t alpha);
uint8_t GetTransparency()const;
private:
//NOTE: Marking a monster for deletion does not trigger any death events. It just simply removes the monster from the field!!
// The way this works is that monsters marked for deletion will cause the monster update loop to detect there's at least one or more monsters that must be deleted and will call erase_if on the list at the end of the iteration loop.
@ -478,6 +488,7 @@ private:
void PerformSpell(const CastInfo&castData);
bool bumpedIntoTerrain=false; //Gets set to true before a strategy executes if the monster runs into some terrain on this frame.
bool attackedByPlayer=false; //Gets set to true before a strategy executes if the monster has been attacked by the player.
uint8_t transparency{255U};
};
struct MonsterSpawner{

View File

@ -183,4 +183,5 @@ enum class Attribute{
SHRAPNEL_CANNON_TIMER,
FLAG_PTR,
WAIT_ONE_TICK,
ALPHA_AMOUNT,
};

View File

@ -89,6 +89,7 @@ void Monster::InitializeStrategies(){
ADD_STRATEGY(SKELETON_CAPTAIN,"Skeleton Captain");
ADD_STRATEGY(SKELETON_CAPTAIN_FLAG,"Skeleton Captain Flag");
ADD_STRATEGY(SKELETON_MAGE,"Skeleton Mage");
ADD_STRATEGY(SPIDER,"Spider");
if(!Monster::monsterStrategies.contains(SKELETON_MAGE))ERR("SKELETON_MAGE is a required dependency for Entity::IsSkeleletonMage()! THIS IS REQUIRED!!");

View File

@ -0,0 +1,63 @@
#pragma region License
/*
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2026 Amy 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 © 2024 The FreeType
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "Monster.h"
#include"AdventuresInLestoria.h"
INCLUDE_game
DEFINE_STRATEGY(SPIDER)
enum Phase{
INIT,
RUN,
};
switch(PHASE()){
case INIT:{
m.F(A::ALPHA_AMOUNT)=m.GetTransparency();
SETPHASE(RUN);
}break;
case RUN:{
const bool isHidden{util::distance(game->GetPlayer()->GetPos(),m.GetPos())>=ConfigPixels("Hide Range")};
m.RunStrategy(GOBLIN_DAGGER);
const float fadeSpd{255*(1/ConfigFloat("Hide Fade Speed"))};
if(isHidden)m.SetTransparency(std::max(0.f,m.F(A::ALPHA_AMOUNT)-fadeSpd*game->GetElapsedTime()));
else m.SetTransparency(std::min(255.f,m.F(A::ALPHA_AMOUNT)+fadeSpd*game->GetElapsedTime()));
m.F(A::ALPHA_AMOUNT)=m.GetTransparency();
}break;
}
END_STRATEGY

View File

@ -21,6 +21,8 @@ Add unit test for IsSkeletonMage()
Thunder Orb startpos should stay in sync with Thunder Orb's position. When near the player, zaps should redirect to the player.
Unit test to check for an expiry time with blank slots/gaps in the effect system.
DEMO
====

View File

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_PATCH 0
#define VERSION_BUILD 13222
#define VERSION_BUILD 13232
#define stringify(a) stringify_(a)
#define stringify_(a) #a

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="315" height="238" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="23">
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="315" height="238" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="24">
<properties>
<property name="Background Music" propertytype="BGM" value="undead_swamp"/>
<property name="Level Type" type="int" propertytype="LevelType" value="0"/>
@ -995,5 +995,10 @@
<property name="spawner" type="object" value="6"/>
</properties>
</object>
<object id="23" template="../maps/Monsters/Spider.tx" x="612" y="4866">
<properties>
<property name="spawner" type="object" value="6"/>
</properties>
</object>
</objectgroup>
</map>

View File

@ -1471,4 +1471,9 @@ MonsterStrategy
Thunder Orb Attack Mult = 1.0x
Thunder Orb Lifetime = 12.0s
}
Spider
{
Hide Range = 500
Hide Fade Speed = 0.5s
}
}

View File

@ -2323,6 +2323,47 @@ Monsters
Death Sound = Slime Dead
Walk Sound = Slime Walk
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
#DROP[0] = Broken Bow,30%,1,1
}
Spider
{
Health = 500
Attack = 51
CollisionDmg = 51
MoveSpd = 120%
Size = 70%
XP = 34
Strategy = Spider
#Size of each animation frame
SheetFrameSize = 32,32
# Setting this to true means every four rows indicates one animation, the ordering of the directions is: NORTH, EAST, SOUTH, WEST
4-Way Spritesheet = False
Animations
{
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse,ReverseOneShot)
# Animations must be defined in the same order as they are in their sprite sheets
# The First Four animations must represent a standing, walking, attack, and death animation. Their names are up to the creator.
IDLE = 2, 0.6, Repeat
WALK = 3, 0.2, Repeat
ATTACK = 4, 0.1, Repeat
DEATH = 4, 0.15, OneShot
STABBING = 3, 0.1, OneShot
SLASH = 1, 0.1, OneShot
STAB = 1, 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] = Broken Bow,30%,1,1
}

View File

@ -39,7 +39,7 @@ CAMPAIGN_3_6 = 2026-01-21 20:30:58.4008008
CAMPAIGN_3_7 = 2026-01-21 20:30:58.4023071
CAMPAIGN_3_8 = 2026-01-21 20:30:58.4049027
CAMPAIGN_3_B1 = 2026-01-21 20:30:58.4336641
CAMPAIGN_4_1 = 2026-03-09 20:41:57.6952132
CAMPAIGN_4_1 = 2026-04-01 21:50:17.3851116
CAMPAIGN_4_2 = 2026-02-26 21:44:13.5210572
CAMPAIGN_4_4 = 2026-02-26 21:44:13.5270745
CAMPAIGN_4_6 = 2026-02-26 21:44:13.5342554

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.2" orientation="orthogonal" renderorder="right-down" width="30" height="20" tilewidth="24" tileheight="24" infinite="1" nextlayerid="3" nextobjectid="52">
<map version="1.10" tiledversion="1.10.2" orientation="orthogonal" renderorder="right-down" width="30" height="20" tilewidth="24" tileheight="24" infinite="1" nextlayerid="3" nextobjectid="53">
<tileset firstgid="1" source="Monsters.tsx"/>
<layer id="1" name="Tile Layer 1" width="30" height="20">
<data encoding="csv"/>
@ -44,5 +44,6 @@
<object id="48" template="Monsters/Skeleton Barbarian.tx" type="Monster" x="-240" y="360"/>
<object id="50" template="Monsters/Skeleton Archer.tx" type="Monster" x="354" y="564"/>
<object id="51" template="Monsters/Skeleton Captain.tx" type="Monster" x="360" y="684"/>
<object id="52" name="Spider" type="Monster" gid="42" x="498" y="642" width="33.6" height="33.6"/>
</objectgroup>
</map>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<template>
<tileset firstgid="1" source="../Monsters.tsx"/>
<object name="Spider" type="Monster" gid="42" width="33.6" height="33.6"/>
</template>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB