Added the ability for items to be activated upon cast instead of on completion of cast. These item effects also get interrupted by any movement.

pull/28/head
sigonasr2 1 year ago
parent fd96b23110
commit 852bbbc5a0
  1. 2
      Crawler/Ability.h
  2. 1
      Crawler/Buff.h
  3. 1
      Crawler/Crawler.cpp
  4. 47
      Crawler/Item.cpp
  5. 4
      Crawler/Item.h
  6. 8
      Crawler/Player.cpp
  7. 2
      Crawler/Version.h
  8. 4
      Crawler/assets/config/items/ItemDatabase.txt
  9. 9
      Crawler/assets/config/items/ItemScript.txt

@ -66,6 +66,8 @@ struct Ability{
bool canCancelCast=false;
InputGroup*input;
std::string icon;
//If set to true, this ability instead activates immediately when a cast occurs. When the cast finishes, nothing happens instead.
bool actionPerformedDuringCast=false;
bool waitForRelease=false;
//Ability action function, returns true if the ability can be casted, otherwise returns false.
// Argument 1: Player* - player pointer

@ -43,6 +43,7 @@ enum BuffType{
SLOWDOWN,
BLOCK_SLOWDOWN,
RESTORATION,
RESTORATION_DURING_CAST,
};
class Crawler;

@ -2236,6 +2236,7 @@ void Crawler::SetLoadoutItem(int slot,std::string itemName){
}break;
}
Ability itemAbility{itemName,"","","Item.Item Cooldown Time"_F,0,inputGroup,"items/"+itemName+".png",VERY_DARK_RED,DARK_RED,PrecastData{GetLoadoutItem(slot).lock()->CastTime(),0,0},true};
itemAbility.actionPerformedDuringCast=GetLoadoutItem(slot).lock()->UseDuringCast();
switch(slot){
case 0:{

@ -105,6 +105,7 @@ void ItemInfo::InitializeItems(){
std::vector<ItemAttribute>statValueList;
uint32_t sellValue=0;
uint32_t buyValue=0;
bool useDuringCast=false;
for(auto&[itemKey,itemValue]:data[key].GetKeys()){
std::string keyName=itemKey;
if(keyName=="Description"){
@ -159,6 +160,9 @@ void ItemInfo::InitializeItems(){
it.enhancement=enhancementStats;
}
if(scriptName!=""){
if(scriptName=="RestoreDuringCast"){
useDuringCast=true;
}
if(!ITEM_SCRIPTS.count(scriptName)){
ERR("Could not load script "<<scriptName<<" for Item "<<key<<"!")
}
@ -173,6 +177,7 @@ void ItemInfo::InitializeItems(){
it.set=setName;
it.buyValue=buyValue;
it.sellValue=sellValue;
it.useDuringCast=useDuringCast;
if(slot.size()>0){
for(std::string&s:slot){
if(!nameToEquipSlot.count(s))ERR("WARNING! Tried to add item "<<it.name<<" to slot "<<s<<" which doesn't exist!");
@ -233,31 +238,53 @@ const uint32_t ItemProps::PropCount(const std::string&prop)const{
void ItemInfo::InitializeScripts(){
ITEM_SCRIPTS["Restore"]=[](Crawler*game,ItemProps props){
auto ParseItemScriptData=[&](const std::string&propName,std::function<void(Crawler*,int)>action,BuffType type){
auto ParseItemScriptData=[&](const std::string&propName,std::function<void(Crawler*,int)>action){
int restoreAmt=props.GetIntProp(propName);
action(game,restoreAmt);
if(restoreAmt>0&&props.PropCount(propName)==3){
game->GetPlayer()->AddBuff(type,props.GetFloatProp(propName,2),restoreAmt,props.GetFloatProp(propName,1),action);
game->GetPlayer()->AddBuff(RESTORATION,props.GetFloatProp(propName,2),restoreAmt,props.GetFloatProp(propName,1),action);
}
};
ParseItemScriptData("HP Restore",[&](Crawler*game,int restoreAmt){
game->GetPlayer()->Heal(restoreAmt);
},RESTORATION);
});
ParseItemScriptData("HP % Restore",[&](Crawler*game,int restoreAmt){
game->GetPlayer()->Heal(int(game->GetPlayer()->GetMaxHealth()*restoreAmt/100.0f));
},RESTORATION);
});
ParseItemScriptData("MP Restore",[&](Crawler*game,int restoreAmt){
game->GetPlayer()->RestoreMana(restoreAmt);
},RESTORATION);
});
ParseItemScriptData("MP % Restore",[&](Crawler*game,int restoreAmt){
game->GetPlayer()->RestoreMana(int(game->GetPlayer()->GetMaxMana()*props.GetIntProp("MP % Restore")/100.f));
},RESTORATION);
});
return true;
};
ITEM_SCRIPTS["Buff"]=[](Crawler*game,ItemProps props){
game->GetPlayer()->AddBuff(BuffType::ATTACK_PCT_UP,props.GetFloatProp("Attack %",1),props.GetFloatProp("Attack %",0)/100);
return true;
};
ITEM_SCRIPTS["RestoreDuringCast"]=[&](Crawler*game,ItemProps props){
auto ParseItemScriptData=[&](const std::string&propName,std::function<void(Crawler*,int)>action){
int restoreAmt=props.GetIntProp(propName);
action(game,restoreAmt);
if(restoreAmt>0&&props.PropCount(propName)==3){
game->GetPlayer()->AddBuff(RESTORATION_DURING_CAST,props.GetFloatProp(propName,2),restoreAmt,props.GetFloatProp(propName,1),action);
}
};
ParseItemScriptData("HP Restore",[&](Crawler*game,int restoreAmt){
game->GetPlayer()->Heal(restoreAmt);
});
ParseItemScriptData("HP % Restore",[&](Crawler*game,int restoreAmt){
game->GetPlayer()->Heal(int(game->GetPlayer()->GetMaxHealth()*restoreAmt/100.0f));
});
ParseItemScriptData("MP Restore",[&](Crawler*game,int restoreAmt){
game->GetPlayer()->RestoreMana(restoreAmt);
});
ParseItemScriptData("MP % Restore",[&](Crawler*game,int restoreAmt){
game->GetPlayer()->RestoreMana(int(game->GetPlayer()->GetMaxMana()*props.GetIntProp("MP % Restore")/100.f));
});
return true;
};
ITEM_SCRIPTS.SetInitialized();
std::cout<<ITEM_SCRIPTS.size()<<" item scripts have been loaded."<<std::endl;
@ -749,3 +776,11 @@ const bool Item::_IsBlank()const{
Item::IsBlankStaticCallCounter++;
return IsBlank();
};
const bool Item::UseDuringCast()const{
return it->UseDuringCast();
}
const bool ItemInfo::UseDuringCast()const{
return useDuringCast;
}

@ -155,6 +155,7 @@ public:
const Stats GetStats()const;
const ItemScript&OnUseAction()const;
const float CastTime()const;
const bool UseDuringCast()const; //When true, the item is activated during the cast instead of after the cast.
const float CooldownTime()const;
//Use ISBLANK macro instead!! This should not be called directly!!
const bool IsBlank()const;
@ -247,6 +248,8 @@ class ItemInfo{
ItemProps customProps;
uint32_t buyValue=0;
uint32_t sellValue=0;
//If true, this item's action is activated at the beginning of the cast instead of after the cast completes.
bool useDuringCast=false;
private:
static void InitializeScripts();
static void InitializeSets();
@ -272,6 +275,7 @@ public:
const uint32_t GetSellValue()const;
const bool CanBeSold()const;
const bool CanBePurchased()const;
const bool UseDuringCast()const;
};
class ItemOverlay{

@ -438,9 +438,13 @@ void Player::Update(float fElapsedTime){
if(CanAct(ability)){
if(ability.cooldown==0&&GetMana()>=ability.manaCost){
if(key.Held()||key.Released()&&&ability==castPrepAbility&&GetState()==State::PREP_CAST){
if(AllowedToCast(ability)&&ability.action(this,{})){
if(AllowedToCast(ability)){
bool allowed=ability.actionPerformedDuringCast;
if(!allowed&&ability.action(this,{}))allowed=true;
if(allowed){
ability.cooldown=ability.COOLDOWN_TIME;
ConsumeMana(ability.manaCost);
}
}else
if(ability.precastInfo.precastTargetingRequired&&GetState()==State::NORMAL){
PrepareCast(ability);
@ -655,6 +659,7 @@ void Player::Moved(){
state=State::NORMAL;
castPrepAbility->waitForRelease=true;
castInfo={"",0};
std::erase_if(buffList,[](Buff&b){return b.type==RESTORATION_DURING_CAST;}); //Remove all buffs that would be applied during a cast, as we got interrupted.
DAMAGENUMBER_LIST.push_back(std::make_shared<DamageNumber>(GetPos(),0,true,INTERRUPT));
}
for(MonsterSpawner&spawner:SPAWNER_LIST){
@ -748,6 +753,7 @@ void Player::CastSpell(Ability&ability){
castPosition=GetPos()+pointToCursor;
}
castInfo={ability.name,ability.precastInfo.castTime,ability.precastInfo.castTime,castPosition};
if(ability.actionPerformedDuringCast){ability.action(this,castPosition);}
SetState(State::CASTING);
}

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

@ -53,9 +53,9 @@ ItemDatabase
}
Bandages
{
ItemScript = Restore
ItemScript = RestoreDuringCast
Description = Restores 30% health points over 6 seconds. The effect can be interrupted.
HP % Restore = 30%
HP % Restore = 5%,1,6
Cast Time = 6.0
Cooldown Time = 5.0
ItemCategory = Consumables

@ -22,4 +22,13 @@ ItemScript
{
Attack % = 0,0.0
}
# Unlike an item or ability that requires a cast to perform, this applies a buff immediately and then moving cancels the buff mid-application.
RestoreDuringCast
{
HP Restore = 0,0.0,0.0
HP % Restore = 0,0.0,0.0
MP Restore = 0,0.0,0.0
MP % Restore = 0,0.0,0.0
}
}
Loading…
Cancel
Save