1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-15 00:05:02 +02:00

[Spells] Added basic support for icons and sounds

* few changes in spell format
* save format changed
This commit is contained in:
alexvins
2014-03-10 16:00:58 +00:00
parent 9f01a92f4c
commit 065b8366fb
22 changed files with 404 additions and 501 deletions

View File

@ -9,8 +9,10 @@ ADVENTURE MAP:
BATTLES: BATTLES:
SPELLS: SPELLS:
* New configuration format: http://wiki.vcmi.eu/index.php?title=Spell_Format
MODS: MODS:
* Mods cas now add new (offensive, buffs, debuffs) spells and change existing
0.94 -> 0.95 (Mar 01 2014) 0.94 -> 0.95 (Mar 01 2014)
GENERAL: GENERAL:

View File

@ -185,6 +185,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
{ {
creatureArtifact = nullptr; //may be set later creatureArtifact = nullptr; //may be set later
artifactImage = nullptr; artifactImage = nullptr;
spellEffectsPics = nullptr;
stack = Stack; stack = Stack;
c = stack->type; c = stack->type;
if(!StackNode) if(!StackNode)
@ -414,25 +415,32 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
if (battleStack) //only during battle if (battleStack) //only during battle
{ {
spellEffectsPics = new CAnimation("SpellInt.def");
//spell effects //spell effects
int printed=0; //how many effect pics have been printed int printed=0; //how many effect pics have been printed
std::vector<si32> spells = battleStack->activeSpells(); std::vector<si32> spells = battleStack->activeSpells();
for(si32 effect : spells) for(si32 effect : spells)
{ {
const si32 imageIndex = effect+1; //there is "null" frame with index 0 in SpellInt.def
std::string spellText; std::string spellText;
if (effect < graphics->spellEffectsPics->ourImages.size()) //not all effects have graphics (for eg. Acid Breath) spellEffectsPics->load(imageIndex);
IImage * effectIcon = spellEffectsPics->getImage(imageIndex,0,false); //todo: better way to determine presence of icon
spellEffectsPics->unload(imageIndex);
if (effectIcon != nullptr) //not all effects have graphics (for eg. Acid Breath)
{ {
spellText = CGI->generaltexth->allTexts[610]; //"%s, duration: %d rounds." spellText = CGI->generaltexth->allTexts[610]; //"%s, duration: %d rounds."
boost::replace_first (spellText, "%s", CGI->spellh->objects[effect]->name); boost::replace_first (spellText, "%s", CGI->spellh->objects[effect]->name);
int duration = battleStack->getBonusLocalFirst(Selector::source(Bonus::SPELL_EFFECT,effect))->turnsRemain; int duration = battleStack->getBonusLocalFirst(Selector::source(Bonus::SPELL_EFFECT,effect))->turnsRemain;
boost::replace_first (spellText, "%d", boost::lexical_cast<std::string>(duration)); boost::replace_first (spellText, "%d", boost::lexical_cast<std::string>(duration));
new CAnimImage("SpellInt", effect + 1, 0, 20 + 52 * printed, 184); new CAnimImage("SpellInt.def", imageIndex, 0, 20 + 52 * printed, 184);
spellEffects.push_back(new LRClickableAreaWText(Rect(20 + 52 * printed, 184, 50, 38), spellText, spellText)); spellEffects.push_back(new LRClickableAreaWText(Rect(20 + 52 * printed, 184, 50, 38), spellText, spellText));
if (++printed >= 10) //we can fit only 10 effects if (++printed >= 10) //we can fit only 10 effects
break; break;
} }
} }
//print current health //print current health
printLine (5, CGI->generaltexth->allTexts[200], battleStack->firstHPleft); printLine (5, CGI->generaltexth->allTexts[200], battleStack->firstHPleft);
} }
@ -689,6 +697,9 @@ CCreatureWindow::~CCreatureWindow()
for (auto & elem : upgResCost) for (auto & elem : upgResCost)
delete elem; delete elem;
bonusItems.clear(); bonusItems.clear();
if(spellEffectsPics!=nullptr)
delete spellEffectsPics;
} }
CBonusItem::CBonusItem() CBonusItem::CBonusItem()

View File

@ -66,6 +66,7 @@ public:
CAdventureMapButton * leftArtRoll, * rightArtRoll; //artifact selection CAdventureMapButton * leftArtRoll, * rightArtRoll; //artifact selection
CAdventureMapButton * passArtToHero; CAdventureMapButton * passArtToHero;
CAnimImage * artifactImage; CAnimImage * artifactImage;
CAnimation * spellEffectsPics; //bitmaps representing spells affecting a stack in battle
//commander level-up //commander level-up
int selectedOption; //index for upgradeOptions int selectedOption; //index for upgradeOptions

View File

@ -145,7 +145,7 @@ void init()
loadDLLClasses(); loadDLLClasses();
const_cast<CGameInfo*>(CGI)->setFromLib(); const_cast<CGameInfo*>(CGI)->setFromLib();
CCS->soundh->initSpellsSounds(CGI->spellh->objects);
logGlobal->infoStream()<<"Initializing VCMI_Lib: "<<tmh.getDiff(); logGlobal->infoStream()<<"Initializing VCMI_Lib: "<<tmh.getDiff();
pomtime.getDiff(); pomtime.getDiff();

View File

@ -177,28 +177,6 @@ Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound)
} }
} }
void CSoundHandler::initSpellsSounds(const std::vector< ConstTransitivePtr<CSpell> > &spells)
{
const JsonNode config(ResourceID("config/sp_sounds.json"));
if (!config["spell_sounds"].isNull())
{
for(const JsonNode &node : config["spell_sounds"].Vector())
{
int spellid = node["id"].Float();
const CSpell *s = CGI->spellh->objects[spellid];
if (vstd::contains(spellSounds, s))
logGlobal->errorStream() << "Spell << " << spellid << " already has a sound";
std::string sound = node["soundfile"].String();
if (sound.empty())
logGlobal->errorStream() << "Error: invalid sound for id "<< spellid;
spellSounds[s] = sound;
}
}
}
// Plays a sound, and return its channel so we can fade it out later // Plays a sound, and return its channel so we can fade it out later
int CSoundHandler::playSound(soundBase::soundID soundID, int repeats) int CSoundHandler::playSound(soundBase::soundID soundID, int repeats)
{ {

View File

@ -57,7 +57,6 @@ public:
void init(); void init();
void release(); void release();
void initSpellsSounds(const std::vector< ConstTransitivePtr<CSpell> > &spells);
void setVolume(ui32 percent); void setVolume(ui32 percent);
// Sounds // Sounds
@ -69,8 +68,6 @@ public:
void setCallback(int channel, std::function<void()> function); void setCallback(int channel, std::function<void()> function);
void soundFinishedCallback(int channel); void soundFinishedCallback(int channel);
std::map<const CSpell*, std::string> spellSounds;
// Sets // Sets
std::vector<soundBase::soundID> pickupSounds; std::vector<soundBase::soundID> pickupSounds;
std::vector<soundBase::soundID> horseSounds; std::vector<soundBase::soundID> horseSounds;

View File

@ -2203,8 +2203,10 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
eraseCurrentPathOf(caster, false); eraseCurrentPathOf(caster, false);
} }
const CSpell * spell = CGI->spellh->objects[spellID]; const CSpell * spell = CGI->spellh->objects[spellID];
if (vstd::contains(CCS->soundh->spellSounds, spell))
CCS->soundh->playSound(CCS->soundh->spellSounds[spell]); auto castSoundPath = spell->getCastSound();
if (!castSoundPath.empty())
CCS->soundh->playSound(castSoundPath);
} }
void CPlayerInterface::eraseCurrentPathOf( const CGHeroInstance * ho, bool checkForExistanceOfPath /*= true */ ) void CPlayerInterface::eraseCurrentPathOf( const CGHeroInstance * ho, bool checkForExistanceOfPath /*= true */ )

View File

@ -147,7 +147,9 @@ CSpellWindow::CSpellWindow(const SDL_Rect &, const CGHeroInstance * _myHero, CPl
leftCorner = BitmapHandler::loadBitmap("SpelTrnL.bmp", true); leftCorner = BitmapHandler::loadBitmap("SpelTrnL.bmp", true);
rightCorner = BitmapHandler::loadBitmap("SpelTrnR.bmp", true); rightCorner = BitmapHandler::loadBitmap("SpelTrnR.bmp", true);
spells = CDefHandler::giveDef("Spells.def");
spells = new CAnimation("Spells.def");
spellTab = CDefHandler::giveDef("SpelTab.def"); spellTab = CDefHandler::giveDef("SpelTab.def");
schools = CDefHandler::giveDef("Schools.def"); schools = CDefHandler::giveDef("Schools.def");
schoolBorders[0] = CDefHandler::giveDef("SplevA.def"); schoolBorders[0] = CDefHandler::giveDef("SplevA.def");
@ -222,6 +224,7 @@ CSpellWindow::~CSpellWindow()
{ {
SDL_FreeSurface(leftCorner); SDL_FreeSurface(leftCorner);
SDL_FreeSurface(rightCorner); SDL_FreeSurface(rightCorner);
spells->unload();
delete spells; delete spells;
delete spellTab; delete spellTab;
delete schools; delete schools;
@ -775,7 +778,7 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[124]); LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[124]);
else else
GH.pushInt (new CObjectListWindow(availableTowns, GH.pushInt (new CObjectListWindow(availableTowns,
new CPicture(graphics->spellscr->ourImages[spell].bitmap, 0, 0, false), new CAnimImage("SPELLSCR",spell),
CGI->generaltexth->jktexts[40], CGI->generaltexth->jktexts[41], CGI->generaltexth->jktexts[40], CGI->generaltexth->jktexts[41],
boost::bind (&CSpellWindow::teleportTo, owner, _1, h))); boost::bind (&CSpellWindow::teleportTo, owner, _1, h)));
} }
@ -836,8 +839,15 @@ void CSpellWindow::SpellArea::showAll(SDL_Surface * to)
return; return;
const CSpell * spell = mySpell.toSpell(); const CSpell * spell = mySpell.toSpell();
owner->spells->load(mySpell);
IImage * icon = owner->spells->getImage(mySpell,0,false);
if(icon != nullptr)
icon->draw(to, pos.x, pos.y);
else
logGlobal->errorStream() << __FUNCTION__ << ": failed to load spell icon for spell with id " << mySpell;
blitAt(owner->spells->ourImages[mySpell].bitmap, pos.x, pos.y, to);
blitAt(owner->schoolBorders[owner->selectedTab >= 4 ? whichSchool : owner->selectedTab]->ourImages[schoolLevel].bitmap, pos.x, pos.y, to); //printing border (indicates level of magic school) blitAt(owner->schoolBorders[owner->selectedTab >= 4 ? whichSchool : owner->selectedTab]->ourImages[schoolLevel].bitmap, pos.x, pos.y, to); //printing border (indicates level of magic school)
SDL_Color firstLineColor, secondLineColor; SDL_Color firstLineColor, secondLineColor;

View File

@ -51,6 +51,7 @@ private:
int spellCost; int spellCost;
CSpellWindow * owner; CSpellWindow * owner;
SpellArea(SDL_Rect pos, CSpellWindow * owner); SpellArea(SDL_Rect pos, CSpellWindow * owner);
void setSpell(SpellID spellID); void setSpell(SpellID spellID);
@ -62,8 +63,10 @@ private:
}; };
SDL_Surface * leftCorner, * rightCorner; SDL_Surface * leftCorner, * rightCorner;
CDefHandler * spells, //pictures of spells
* spellTab, //school select CAnimation * spells; //pictures of spells
CDefHandler * spellTab, //school select
* schools, //schools' pictures * schools, //schools' pictures
* schoolBorders [4]; //schools' 'borders': [0]: air, [1]: fire, [2]: water, [3]: earth * schoolBorders [4]; //schools' 'borders': [0]: air, [1]: fire, [2]: water, [3]: earth

View File

@ -1841,7 +1841,7 @@ void CObjectListWindow::CItem::clickLeft(tribool down, bool previousState)
parent->changeSelection(index); parent->changeSelection(index);
} }
CObjectListWindow::CObjectListWindow(const std::vector<int> &_items, CPicture * titlePic, std::string _title, std::string _descr, CObjectListWindow::CObjectListWindow(const std::vector<int> &_items, CIntObject * titlePic, std::string _title, std::string _descr,
std::function<void(int)> Callback): std::function<void(int)> Callback):
CWindowObject(PLAYER_COLORED, "TPGATE"), CWindowObject(PLAYER_COLORED, "TPGATE"),
onSelect(Callback) onSelect(Callback)
@ -1855,7 +1855,7 @@ CObjectListWindow::CObjectListWindow(const std::vector<int> &_items, CPicture *
init(titlePic, _title, _descr); init(titlePic, _title, _descr);
} }
CObjectListWindow::CObjectListWindow(const std::vector<std::string> &_items, CPicture * titlePic, std::string _title, std::string _descr, CObjectListWindow::CObjectListWindow(const std::vector<std::string> &_items, CIntObject * titlePic, std::string _title, std::string _descr,
std::function<void(int)> Callback): std::function<void(int)> Callback):
CWindowObject(PLAYER_COLORED, "TPGATE"), CWindowObject(PLAYER_COLORED, "TPGATE"),
onSelect(Callback) onSelect(Callback)
@ -1868,7 +1868,7 @@ CObjectListWindow::CObjectListWindow(const std::vector<std::string> &_items, CPi
init(titlePic, _title, _descr); init(titlePic, _title, _descr);
} }
void CObjectListWindow::init(CPicture * titlePic, std::string _title, std::string _descr) void CObjectListWindow::init(CIntObject * titlePic, std::string _title, std::string _descr)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;

View File

@ -538,20 +538,20 @@ class CObjectListWindow : public CWindowObject
CLabel * descr; CLabel * descr;
CListBox * list; CListBox * list;
CPicture *titleImage;//title image (castle gate\town portal picture) CIntObject * titleImage;//title image (castle gate\town portal picture)
CAdventureMapButton *ok, *exit; CAdventureMapButton *ok, *exit;
std::vector< std::pair<int, std::string> > items;//all items present in list std::vector< std::pair<int, std::string> > items;//all items present in list
void init(CPicture * titlePic, std::string _title, std::string _descr); void init(CIntObject * titlePic, std::string _title, std::string _descr);
public: public:
size_t selected;//index of currently selected item size_t selected;//index of currently selected item
/// Callback will be called when OK button is pressed, returns id of selected item. initState = initially selected item /// Callback will be called when OK button is pressed, returns id of selected item. initState = initially selected item
/// Image can be nullptr /// Image can be nullptr
///item names will be taken from map objects ///item names will be taken from map objects
CObjectListWindow(const std::vector<int> &_items, CPicture * titlePic, std::string _title, std::string _descr, CObjectListWindow(const std::vector<int> &_items, CIntObject * titlePic, std::string _title, std::string _descr,
std::function<void(int)> Callback); std::function<void(int)> Callback);
CObjectListWindow(const std::vector<std::string> &_items, CPicture * titlePic, std::string _title, std::string _descr, CObjectListWindow(const std::vector<std::string> &_items, CIntObject * titlePic, std::string _title, std::string _descr,
std::function<void(int)> Callback); std::function<void(int)> Callback);
CIntObject *genItem(size_t index); CIntObject *genItem(size_t index);

View File

@ -17,12 +17,14 @@
#include "../lib/CCreatureHandler.h" #include "../lib/CCreatureHandler.h"
#include "CBitmapHandler.h" #include "CBitmapHandler.h"
#include "../lib/CObjectHandler.h" #include "../lib/CObjectHandler.h"
#include "../lib/CSpellHandler.h"
#include "../lib/CDefObjInfoHandler.h" #include "../lib/CDefObjInfoHandler.h"
#include "../lib/CGameState.h" #include "../lib/CGameState.h"
#include "../lib/JsonNode.h" #include "../lib/JsonNode.h"
#include "../lib/vcmi_endian.h" #include "../lib/vcmi_endian.h"
#include "../lib/GameConstants.h" #include "../lib/GameConstants.h"
#include "../lib/CStopWatch.h" #include "../lib/CStopWatch.h"
#include "CAnimation.h"
using namespace boost::assign; using namespace boost::assign;
using namespace CSDL_Ext; using namespace CSDL_Ext;
@ -116,8 +118,6 @@ void Graphics::initializeBattleGraphics()
battleACToDef[ACid] = toAdd; battleACToDef[ACid] = toAdd;
} }
spellEffectsPics = CDefHandler::giveDefEss("SpellInt.def");
} }
Graphics::Graphics() Graphics::Graphics()
{ {
@ -129,7 +129,6 @@ Graphics::Graphics()
tasks += boost::bind(&Graphics::loadErmuToPicture,this); tasks += boost::bind(&Graphics::loadErmuToPicture,this);
tasks += boost::bind(&Graphics::initializeImageLists,this); tasks += boost::bind(&Graphics::initializeImageLists,this);
tasks += GET_DEF_ESS(resources32,"RESOURCE.DEF"); tasks += GET_DEF_ESS(resources32,"RESOURCE.DEF");
tasks += GET_DEF_ESS(spellscr,"SPELLSCR.DEF");
tasks += GET_DEF_ESS(heroMoveArrows,"ADAG.DEF"); tasks += GET_DEF_ESS(heroMoveArrows,"ADAG.DEF");
CThreadHelper th(&tasks,std::max((ui32)1,boost::thread::hardware_concurrency())); CThreadHelper th(&tasks,std::max((ui32)1,boost::thread::hardware_concurrency()));
@ -411,4 +410,12 @@ void Graphics::initializeImageLists()
addImageListEntry(info.icons[1][1] + 2, "ITPA", info.iconSmall[1][1]); addImageListEntry(info.icons[1][1] + 2, "ITPA", info.iconSmall[1][1]);
} }
} }
for(const CSpell * spell : CGI->spellh->objects)
{
addImageListEntry(spell->id, "SPELLS", spell->iconBook);
addImageListEntry(spell->id+1, "SPELLINT", spell->iconEffect);
addImageListEntry(spell->id, "SPELLBON", spell->iconScenarioBonus);
addImageListEntry(spell->id, "SPELLSCR", spell->iconScroll);
}
} }

View File

@ -26,6 +26,7 @@ struct InfoAboutHero;
struct InfoAboutTown; struct InfoAboutTown;
class CGObjectInstance; class CGObjectInstance;
class ObjectTemplate; class ObjectTemplate;
class CAnimation;
enum EFonts enum EFonts
{ {
@ -41,7 +42,7 @@ public:
//Fonts //Fonts
static const int FONTS_NUMBER = 9; static const int FONTS_NUMBER = 9;
IFont * fonts[FONTS_NUMBER]; IFont * fonts[FONTS_NUMBER];
\
//various graphics //various graphics
SDL_Color * playerColors; //array [8] SDL_Color * playerColors; //array [8]
SDL_Color * neutralColor; SDL_Color * neutralColor;
@ -66,9 +67,6 @@ public:
//for battles //for battles
std::vector< std::vector< std::string > > battleBacks; //battleBacks[terType] - vector of possible names for certain terrain type std::vector< std::vector< std::string > > battleBacks; //battleBacks[terType] - vector of possible names for certain terrain type
std::map< int, std::vector < std::string > > battleACToDef; //maps AC format to vector of appropriate def names std::map< int, std::vector < std::string > > battleACToDef; //maps AC format to vector of appropriate def names
CDefEssential * spellEffectsPics; //bitmaps representing spells affecting a stack in battle
//spells
CDefEssential *spellscr; //spell on the scroll 83x61
//functions //functions
Graphics(); Graphics();
void initializeBattleGraphics(); void initializeBattleGraphics();

View File

@ -1230,8 +1230,10 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
std::vector< std::string > anims; //for magic arrow and ice bolt std::vector< std::string > anims; //for magic arrow and ice bolt
if (vstd::contains(CCS->soundh->spellSounds, &spell)) const std::string& castSoundPath = spell.getCastSound();
CCS->soundh->playSound(CCS->soundh->spellSounds[&spell]);
if(!castSoundPath.empty())
CCS->soundh->playSound(castSoundPath);
switch(sc->id) switch(sc->id)
{ {

View File

@ -96,7 +96,7 @@
}, },
"defaultGainChance":{ "defaultGainChance":{
"type": "nomber", "type": "number",
"description": "Gain chance by default for all factions" "description": "Gain chance by default for all factions"
}, },
@ -115,7 +115,7 @@
}, },
"anim":{ "anim":{
"type": "number", "type": "number",
"description": "Main effect animation (AC format), -1 - none", "description": "Main effect animation (AC format), -1 - none, deprecated",
"minimum": -1 "minimum": -1
}, },
"counters":{ "counters":{
@ -178,11 +178,42 @@
"type": "string", "type": "string",
"description": "Resourse path of icon for SPELL_IMMUNITY bonus (relative to DATA or SPRITES)", "description": "Resourse path of icon for SPELL_IMMUNITY bonus (relative to DATA or SPRITES)",
"format" : "imageFile" "format" : "imageFile"
},
"iconScenarioBonus":{
"type": "string",
"description": "Resourse path of icon for scenario bonus" ,
"format" : "imageFile"
},
"iconEffect":{
"type": "string",
"description": "Resourse path of icon for spell effects during battle" ,
"format" : "imageFile"
},
"iconBook":{
"type": "string",
"description":"Resourse path of icon for spellbook" ,
"format" : "imageFile"
},
"iconScroll":{
"type": "string",
"description": "Resourse path of icon for spell scrolls",
"format": "imageFile"
} }
} }
}, },
"sounds":{
"type": "object",
"additionalProperties" : false,
"properties":{
"cast":{
"type": "string",
"description": "Resourse path of cast sound"
}
}
},
"levels":{ "levels":{
"type": "object", "type": "object",
"additionalProperties" : false, "additionalProperties" : false,

View File

@ -1,415 +1,3 @@
// Sounds associated with spells
// "name" is not currently used in game
{
"spell_sounds":
[
{
"id": 0 ,
"name":"Summon boat",
"soundfile":"SUMMBOAT.wav"
},
{
"id": 1 ,
"name":"Scuttle boat",
"soundfile":"SCUTBOAT.wav"
},
{
"id": 2 ,
"name":"Visions",
"soundfile":"VISIONS.wav"
},
{
"id": 3 ,
"name":"View Earth",
"soundfile":"VIEW.wav"
},
{
"id": 4 ,
"name":"Disguise",
"soundfile":"DISGUISE.wav"
},
{
"id": 5 ,
"name":"View Air",
"soundfile":"VIEW.wav"
},
{
"id": 6 ,
"name":"Fly",
"soundfile":"FLYSPELL.wav"
},
{
"id": 7 ,
"name":"Water walking",
"soundfile":"WATRWALK.wav"
},
{
"id": 8 ,
"name":"Dimension doors",
"soundfile":"TELPTOUT.wav"
},
{
"id": 9 ,
"name":"Town Portal",
"soundfile":"TELPTOUT.wav"
},
{
"id": 10 ,
"name":"Quick sands",
"soundfile":"QUIKSAND.wav"
},
{
"id": 12 ,
"name":"Force field",
"soundfile":"FORCEFLD.wav"
},
{
"id": 13 ,
"name":"Fire wall",
"soundfile":"FIREWALL.wav"
},
{
"id": 14 ,
"name":"Earthquake",
"soundfile":"ERTHQUAK.wav"
},
{
"id": 15,
"soundfile": "MAGICBLT.wav",
"name": "magic arrow"
},
{
"id": 16,
"soundfile": "ICERAY.wav",
"name": "ice bolt"
},
{
"id": 17,
"soundfile": "LIGHTBLT.wav",
"name": "lightning bolt"
},
{
"id": 18 ,
"name":"Implosion",
"soundfile":"DECAY.wav"
},
{
"id": 19 ,
"name":"Chaon lighting",
"soundfile":"CHAINLTE.wav"
},
{
"id": 20,
"soundfile": "FROSTING.wav",
"name": "frost ring"
},
{
"id": 21,
"soundfile": "FIREBALL.wav",
"name": "fireball"
},
{
"id": 22 ,
"name":"Inferno",
"soundfile":"FIREBLST.wav"
},
{
"id": 23,
"soundfile": "METEOR.wav",
"name": "meteor shower"
},
{
"id": 24,
"soundfile": "DEATHRIP.wav",
"name": "death ripple"
},
{
"id": 25 ,
"name":"Destroy undead",
"soundfile":"COLDRING.wav"
},
{
"id": 26,
"soundfile": "ARMGEDN.wav",
"name": "armageddon"
},
{
"id": 27,
"soundfile": "SHIELD.wav",
"name": "shield "
},
{
"id": 28,
"soundfile": "AIRSHELD.wav",
"name": "air shield"
},
{
"id": 29 ,
"name":"fireshield cast",
"soundfile":"FIRESHIE.wav"
},
// It looks that fireshield has two separate souds. Disabling one of them for now
// {
// "id": 29 ,
// "name":"fireshield effect",
// "soundfile":"FIRESHLD.wav"
// },
{
"id": 30,
"soundfile": "PROTECTA.wav",
"name": "protection from air"
},
{
"id": 31,
"soundfile": "PROTECTF.wav",
"name": "protection from fire"
},
{
"id": 32,
"soundfile": "PROTECTW.wav",
"name": "protection from water"
},
{
"id": 33,
"soundfile": "PROTECTE.wav",
"name": "protection from earth"
},
{
"id": 34,
"soundfile": "ANIMDEAD.wav"
},
{
"id": 35,
"soundfile": "DISPELL.wav",
"name": "dispell"
},
{
"id": 36 ,
"name":"Magic mirror",
"soundfile":"BACKLASH.wav"
},
{
"id": 37 ,
"name":"Cure",
"soundfile":"CURE.wav"
},
{
"id": 38 ,
"name":"Resurrect",
"soundfile":"RESURECT.wav"
},
{
"id": 39,
"soundfile": "ANIMDEAD.wav"
},
{
"id": 40 ,
"name":"Sacrifice",
"soundfile":"SACRIF1.wav"
},
{
"id": 41,
"soundfile": "BLESS.wav",
"name": "bless"
},
{
"id": 42,
"soundfile": "CURSE.wav",
"name": "curse"
},
{
"id": 43,
"soundfile": "BLOODLUS.wav",
"name": "bloodlust"
},
{
"id": 44,
"soundfile": "PRECISON.wav",
"name": "precision"
},
{
"id": 45,
"soundfile": "WEAKNESS.wav",
"name": "weakness"
},
{
"id": 46,
"soundfile": "TUFFSKIN.wav",
"name": "stone skin"
},
{
"id": 47,
"soundfile": "DISRUPTR.wav",
"name": "disrupting ray"
},
{
"id": 48,
"soundfile": "PRAYER.wav",
"name": "prayer"
},
{
"id": 49,
"soundfile": "MIRTH.wav",
"name": "mirth"
},
{
"id": 50,
"soundfile": "SORROW.wav",
"name": "sorrow"
},
{
"id": 51,
"soundfile": "FORTUNE.wav",
"name": "fortune"
},
{
"id": 52,
"soundfile": "MISFORT.wav",
"name": "misfortune"
},
{
"id": 53,
"soundfile": "HASTE.wav",
"name": "haste"
},
{
"id": 54,
"soundfile": "MUCKMIRE.wav",
"name": "slow"
},
{
"id": 55,
"soundfile": "SLAYER.wav",
"name": "slayer"
},
{
"id": 56,
"soundfile": "FRENZY.wav",
"name": "frenzy"
},
{
"id": 57 ,
"name":"Titan Bolt",
"soundfile":"LIGHTBLT.wav"
},
{
"id": 58 ,
"name":"Counterstrike",
"soundfile":"CNTRSTRK.wav"
},
{
"id": 59 ,
"name":"Berserk",
"soundfile":"BERSERK.wav"
},
{
"id": 60,
"soundfile": "HYPNOTIZ.wav",
"name": "forgetfulness"
},
{
"id": 61,
"soundfile": "FORGET.wav",
"name": "forgetfulness"
},
{
"id": 62,
"soundfile": "BLIND.wav"
},
{
"id": 63 ,
"name":"Teleport",
"soundfile":"TELPTOUT.wav"
},
{
"id": 64 ,
"name":"Remove obstacle",
"soundfile":"REMOVEOB.wav"
},
{
"id": 65 ,
"name":"Clone",
"soundfile":"CLONE.wav"
},
{
"id": 66 ,
"name":"Summon elementals",
"soundfile":"SUMNELM.wav"
},
{
"id": 67 ,
"name":"Summon elementals",
"soundfile":"SUMNELM.wav"
},
{
"id": 68 ,
"name":"Summon elementals",
"soundfile":"SUMNELM.wav"
},
{
"id": 69 ,
"name":"Summon elementals",
"soundfile":"SUMNELM.wav"
},
{
"id": 70,
"soundfile": "PARALYZE.wav",
"name": "stone gaze and paralyze"
},
{
"id": 71,
"soundfile": "POISON.wav",
"name": "poison"
},
{
"id": 72,
"soundfile": "BIND.wav",
"name": " bind"
},
{
"id": 73,
"soundfile": "DISEASE.wav",
"name": ""
},
{
"id": 74,
"soundfile": "PARALYZE.wav",
"name": ""
},
{
"id": 75,
"soundfile": "AGE.wav",
"name": "aging"
},
{
"id": 76,
"soundfile": "DEATHCLD.wav",
"name": "death cloud"
},
{
"id": 77,
"soundfile": "LIGHTBLT.wav",
"name": "thunder"
},
{
"id": 78,
"soundfile": "DISPELL.wav",
"name": "dispell helpful spells"
},
{
"id": 79,
"soundfile": "DEATHSTR.wav",
"name": "Death Stare"
},
{
"id": 80,
"soundfile": "ACID.wav",
"name": " Acid breath / defence piercing"
}
]
}
// Several probably missing sounds of creature abilities // Several probably missing sounds of creature abilities
// ACID.WAV Acid breath Rust Dragons // ACID.WAV Acid breath Rust Dragons

View File

@ -2,6 +2,9 @@
"summonBoat" : { "summonBoat" : {
"index" : 0, "index" : 0,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "SUMMBOAT"
},
"levels" :{ "levels" :{
"none":{ "none":{
"range" : "X" "range" : "X"
@ -23,8 +26,10 @@
"scuttleBoat" : { "scuttleBoat" : {
"index" : 1, "index" : 1,
"anim" : -1, "anim" : -1,
"levels" : "sounds": {
{ "cast": "SCUTBOAT"
},
"levels" : {
"none": { "none": {
"range" : "X" "range" : "X"
}, },
@ -45,6 +50,9 @@
"visions" : { "visions" : {
"index" : 2, "index" : 2,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "VISIONS"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -66,6 +74,9 @@
"viewEarth" : { "viewEarth" : {
"index" : 3, "index" : 3,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "VIEW"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -87,6 +98,9 @@
"disguise" : { "disguise" : {
"index" : 4, "index" : 4,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "DISGUISE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -108,6 +122,9 @@
"viewAir" : { "viewAir" : {
"index" : 5, "index" : 5,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "VIEW"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -129,6 +146,9 @@
"fly" : { "fly" : {
"index" : 6, "index" : 6,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "FLYSPELL"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -150,6 +170,9 @@
"waterWalk" : { "waterWalk" : {
"index" : 7, "index" : 7,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "WATRWALK"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -171,6 +194,9 @@
"dimensionDoor" : { "dimensionDoor" : {
"index" : 8, "index" : 8,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "TELPTOUT"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -192,6 +218,9 @@
"townPortal" : { "townPortal" : {
"index" : 9, "index" : 9,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "TELPTOUT"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -213,6 +242,9 @@
"quicksand" : { "quicksand" : {
"index" : 10, "index" : 10,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "QUIKSAND"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -234,6 +266,9 @@
"landMine" : { "landMine" : {
"index" : 11, "index" : 11,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": ""
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -259,6 +294,9 @@
"forceField" : { "forceField" : {
"index" : 12, "index" : 12,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "FORCEFLD"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -280,6 +318,9 @@
"fireWall" : { "fireWall" : {
"index" : 13, "index" : 13,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "FIREWALL"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -305,6 +346,9 @@
"earthquake" : { "earthquake" : {
"index" : 14, "index" : 14,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "ERTHQUAK"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -326,6 +370,9 @@
"magicArrow" : { "magicArrow" : {
"index" : 15, "index" : 15,
"anim" : 64, "anim" : 64,
"sounds": {
"cast": "MAGICBLT"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -352,6 +399,9 @@
"iceBolt" : { "iceBolt" : {
"index" : 16, "index" : 16,
"anim" : 46, "anim" : 46,
"sounds": {
"cast": "ICERAY"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -378,6 +428,9 @@
"lightningBolt" : { "lightningBolt" : {
"index" : 17, "index" : 17,
"anim" : 38, "anim" : 38,
"sounds": {
"cast": "LIGHTBLT"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -404,6 +457,9 @@
"implosion" : { "implosion" : {
"index" : 18, "index" : 18,
"anim" : 10, "anim" : 10,
"sounds": {
"cast": "DECAY"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -431,6 +487,9 @@
"chainLightning" : { "chainLightning" : {
"index" : 19, "index" : 19,
"anim" : 38, "anim" : 38,
"sounds": {
"cast": "CHAINLTE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -454,6 +513,9 @@
"frostRing" : { "frostRing" : {
"index" : 20, "index" : 20,
"anim" : 45, "anim" : 45,
"sounds": {
"cast": "FROSTING"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "1" "range" : "1"
@ -480,6 +542,9 @@
"fireball" : { "fireball" : {
"index" : 21, "index" : 21,
"anim" : 53, "anim" : 53,
"sounds": {
"cast": "FIREBALL"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0,1" "range" : "0,1"
@ -506,6 +571,9 @@
"inferno" : { "inferno" : {
"index" : 22, "index" : 22,
"anim" : 9, "anim" : 9,
"sounds": {
"cast": "FIREBLST"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0-2" "range" : "0-2"
@ -532,6 +600,9 @@
"meteorShower" : { "meteorShower" : {
"index" : 23, "index" : 23,
"anim" : 16, "anim" : 16,
"sounds": {
"cast": "METEOR"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0,1" "range" : "0,1"
@ -558,6 +629,9 @@
"deathRipple" : { "deathRipple" : {
"index" : 24, "index" : 24,
"anim" : 8, "anim" : 8,
"sounds": {
"cast": "DEATHRIP"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -586,6 +660,9 @@
"destroyUndead" : { "destroyUndead" : {
"index" : 25, "index" : 25,
"anim" : 29, "anim" : 29,
"sounds": {
"cast": "COLDRING"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -615,6 +692,9 @@
"armageddon" : { "armageddon" : {
"index" : 26, "index" : 26,
"anim" : 12, "anim" : 12,
"sounds": {
"cast": "ARMGEDN"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -641,6 +721,9 @@
"shield" : { "shield" : {
"index" : 27, "index" : 27,
"anim" : 27, "anim" : 27,
"sounds": {
"cast": "SHIELD"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -690,6 +773,9 @@
"airShield" : { "airShield" : {
"index" : 28, "index" : 28,
"anim" : 2, "anim" : 2,
"sounds": {
"cast": "AIRSHELD"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -739,6 +825,12 @@
"fireShield" : { "fireShield" : {
"index" : 29, "index" : 29,
"anim" : 11, "anim" : 11,
"sounds": {
"cast": "FIRESHIE"
},
// It looks that fireshield has two separate sounds
// "soundfile":"FIRESHLD.wav"
//
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -784,6 +876,9 @@
"protectAir" : { "protectAir" : {
"index" : 30, "index" : 30,
"anim" : 22, "anim" : 22,
"sounds": {
"cast": "PROTECTA"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -833,6 +928,9 @@
"protectFire" : { "protectFire" : {
"index" : 31, "index" : 31,
"anim" : 24, "anim" : 24,
"sounds": {
"cast": "PROTECTF"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -882,6 +980,9 @@
"protectWater" : { "protectWater" : {
"index" : 32, "index" : 32,
"anim" : 23, "anim" : 23,
"sounds": {
"cast": "PROTECTW"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -931,6 +1032,9 @@
"protectEarth" : { "protectEarth" : {
"index" : 33, "index" : 33,
"anim" : 26, "anim" : 26,
"sounds": {
"cast": "PROTECTE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -980,6 +1084,9 @@
"antiMagic" : { "antiMagic" : {
"index" : 34, "index" : 34,
"anim" : 5, "anim" : 5,
"sounds": {
"cast": "ANTIMAGK"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1033,6 +1140,9 @@
"dispel" : { "dispel" : {
"index" : 35, "index" : 35,
"anim" : 41, "anim" : 41,
"sounds": {
"cast": "DISPELL"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -1054,6 +1164,9 @@
"magicMirror" : { "magicMirror" : {
"index" : 36, "index" : 36,
"anim" : 3, "anim" : 3,
"sounds": {
"cast": "BACKLASH"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1103,6 +1216,9 @@
"cure" : { "cure" : {
"index" : 37, "index" : 37,
"anim" : 39, "anim" : 39,
"sounds": {
"cast": "CURE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -1124,6 +1240,9 @@
"resurrection" : { "resurrection" : {
"index" : 38, "index" : 38,
"anim" : 79, "anim" : 79,
"sounds": {
"cast": "RESURECT"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -1150,6 +1269,9 @@
"animateDead" : { "animateDead" : {
"index" : 39, "index" : 39,
"anim" : 79, "anim" : 79,
"sounds": {
"cast": "ANIMDEAD"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -1175,6 +1297,9 @@
"sacrifice" : { "sacrifice" : {
"index" : 40, "index" : 40,
"anim" : 79, "anim" : 79,
"sounds": {
"cast": "SACRIF1"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -1201,6 +1326,9 @@
"bless" : { "bless" : {
"index" : 41, "index" : 41,
"anim" : 36, "anim" : 36,
"sounds": {
"cast": "BLESS"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1264,6 +1392,9 @@
"curse" : { "curse" : {
"index" : 42, "index" : 42,
"anim" : 40, "anim" : 40,
"sounds": {
"cast": "CURSE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1331,6 +1462,9 @@
"bloodlust" : { "bloodlust" : {
"index" : 43, "index" : 43,
"anim" : 4, "anim" : 4,
"sounds": {
"cast": "BLOODLUS"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1391,6 +1525,9 @@
"precision" : { "precision" : {
"index" : 44, "index" : 44,
"anim" : 25, "anim" : 25,
"sounds": {
"cast": "PRECISON"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1451,6 +1588,9 @@
"weakness" : { "weakness" : {
"index" : 45, "index" : 45,
"anim" : 56, "anim" : 56,
"sounds": {
"cast": "WEAKNESS"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1507,6 +1647,9 @@
"stoneSkin" : { "stoneSkin" : {
"index" : 46, "index" : 46,
"anim" : 54, "anim" : 54,
"sounds": {
"cast": "TUFFSKIN"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1561,6 +1704,9 @@
"index" : 47, "index" : 47,
"targetType" : "CREATURE", //fix, dont remove "targetType" : "CREATURE", //fix, dont remove
"anim" : 14, "anim" : 14,
"sounds": {
"cast": "DISRUPTR"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1618,6 +1764,9 @@
"prayer" : { "prayer" : {
"index" : 48, "index" : 48,
"anim" : 0, "anim" : 0,
"sounds": {
"cast": "PRAYER"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1719,6 +1868,9 @@
"mirth" : { "mirth" : {
"index" : 49, "index" : 49,
"anim" : 20, "anim" : 20,
"sounds": {
"cast": "MIRTH"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1771,6 +1923,9 @@
"sorrow" : { "sorrow" : {
"index" : 50, "index" : 50,
"anim" : 30, "anim" : 30,
"sounds": {
"cast": "SORROW"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1828,6 +1983,9 @@
"fortune" : { "fortune" : {
"index" : 51, "index" : 51,
"anim" : 18, "anim" : 18,
"sounds": {
"cast": "FORTUNE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1880,6 +2038,9 @@
"misfortune" : { "misfortune" : {
"index" : 52, "index" : 52,
"anim" : 48, "anim" : 48,
"sounds": {
"cast": "MISFORT"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1932,6 +2093,9 @@
"haste" : { "haste" : {
"index" : 53, "index" : 53,
"anim" : 31, "anim" : 31,
"sounds": {
"cast": "HASTE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -1991,6 +2155,9 @@
"slow" : { "slow" : {
"index" : 54, "index" : 54,
"anim" : 19, "anim" : 19,
"sounds": {
"cast": "MUCKMIRE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2055,6 +2222,9 @@
"slayer" : { "slayer" : {
"index" : 55, "index" : 55,
"anim" : 28, "anim" : 28,
"sounds": {
"cast": "SLAYER"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2104,6 +2274,9 @@
"frenzy" : { "frenzy" : {
"index" : 56, "index" : 56,
"anim" : 17, "anim" : 17,
"sounds": {
"cast": "FRENZY"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2153,6 +2326,9 @@
"titanBolt" : { "titanBolt" : {
"index" : 57, "index" : 57,
"anim" : 38, "anim" : 38,
"sounds": {
"cast": "LIGHTBLT"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -2177,6 +2353,9 @@
"counterstrike" : { "counterstrike" : {
"index" : 58, "index" : 58,
"anim" : 7, "anim" : 7,
"sounds": {
"cast": "CNTRSTRK"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2226,6 +2405,9 @@
"berserk" : { "berserk" : {
"index" : 59, "index" : 59,
"anim" : 35, "anim" : 35,
"sounds": {
"cast": "BERSERK"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2281,6 +2463,9 @@
"hypnotize" : { "hypnotize" : {
"index" : 60, "index" : 60,
"anim" : 21, "anim" : 21,
"sounds": {
"cast": "HYPNOTIZ"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2337,6 +2522,9 @@
"index" : 61, "index" : 61,
"targetType" : "CREATURE_EXPERT_MASSIVE", //fix dont remove "targetType" : "CREATURE_EXPERT_MASSIVE", //fix dont remove
"anim" : 42, "anim" : 42,
"sounds": {
"cast": "FORGET"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2394,6 +2582,9 @@
"blind" : { "blind" : {
"index" : 62, "index" : 62,
"anim" : 6, "anim" : 6,
"sounds": {
"cast": "BLIND"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2513,6 +2704,9 @@
"teleport" : { "teleport" : {
"index" : 63, "index" : 63,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "TELPTOUT"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -2537,6 +2731,9 @@
"removeObstacle" : { "removeObstacle" : {
"index" : 64, "index" : 64,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "REMOVEOB"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -2558,6 +2755,9 @@
"clone" : { "clone" : {
"index" : 65, "index" : 65,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "CLONE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -2582,6 +2782,9 @@
"fireElemental" : { "fireElemental" : {
"index" : 66, "index" : 66,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "SUMNELM"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -2603,6 +2806,9 @@
"earthElemental" : { "earthElemental" : {
"index" : 67, "index" : 67,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "SUMNELM"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -2624,6 +2830,9 @@
"waterElemental" : { "waterElemental" : {
"index" : 68, "index" : 68,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "SUMNELM"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -2645,6 +2854,9 @@
"airElemental" : { "airElemental" : {
"index" : 69, "index" : 69,
"anim" : -1, "anim" : -1,
"sounds": {
"cast": "SUMNELM"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "X" "range" : "X"
@ -2666,6 +2878,9 @@
"stoneGaze" : { "stoneGaze" : {
"index" : 70, "index" : 70,
"anim" : 70, "anim" : 70,
"sounds": {
"cast": "PARALYZE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2751,6 +2966,9 @@
"poison" : { "poison" : {
"index" : 71, "index" : 71,
"anim" : 67, "anim" : 67,
"sounds": {
"cast": "POISON"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2832,6 +3050,9 @@
"bind" : { "bind" : {
"index" : 72, "index" : 72,
"anim" : 68, "anim" : 68,
"sounds": {
"cast": "BIND"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2885,6 +3106,9 @@
"disease" : { "disease" : {
"index" : 73, "index" : 73,
"anim" : 69, "anim" : 69,
"sounds": {
"cast": "DISEASE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -2966,6 +3190,9 @@
"paralyze" : { "paralyze" : {
"index" : 74, "index" : 74,
"anim" : 70, "anim" : 70,
"sounds": {
"cast": "PARALYZE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -3051,6 +3278,9 @@
"age" : { "age" : {
"index" : 75, "index" : 75,
"anim" : 71, "anim" : 71,
"sounds": {
"cast": "AGE"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -3108,6 +3338,9 @@
"deathCloud" : { "deathCloud" : {
"index" : 76, "index" : 76,
"anim" : 72, "anim" : 72,
"sounds": {
"cast": "DEATHCLD"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0-1" "range" : "0-1"
@ -3133,6 +3366,9 @@
"thunderbolt" : { "thunderbolt" : {
"index" : 77, "index" : 77,
"anim" : 38, "anim" : 38,
"sounds": {
"cast": "LIGHTBLT"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -3156,6 +3392,9 @@
"dispelHelpful" : { "dispelHelpful" : {
"index" : 78, "index" : 78,
"anim" : 41, "anim" : 41,
"sounds": {
"cast": "DISPELL"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -3178,6 +3417,9 @@
"deathStare" : { "deathStare" : {
"index" : 79, "index" : 79,
"anim" : 80, "anim" : 80,
"sounds": {
"cast": "DEATHSTR"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"
@ -3203,6 +3445,9 @@
"acidBreath" : { "acidBreath" : {
"index" : 80, "index" : 80,
"anim" : 81, "anim" : 81,
"sounds": {
"cast": "ACID"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0", "range" : "0",
@ -3260,6 +3505,9 @@
"acidBreathDamage" : { "acidBreathDamage" : {
"index" : 81, "index" : 81,
"anim" : 81, "anim" : 81,
"sounds": {
"cast": "ACID"
},
"levels" : { "levels" : {
"none":{ "none":{
"range" : "0" "range" : "0"

View File

@ -2063,7 +2063,7 @@ std::set<const CStack*> CBattleInfoCallback::getAffectedCreatures(const CSpell *
{ {
if(const CStack * st = battleGetStackByPos(hex, onlyAlive)) if(const CStack * st = battleGetStackByPos(hex, onlyAlive))
{ {
if (spell->id == 76) //Death Cloud //TODO: fireball and fire immunity if (spell->id == SpellID::DEATH_CLOUD) //Death Cloud //TODO: fireball and fire immunity
{ {
if (st->isLiving() || st->coversPos(destinationTile)) //directly hit or alive if (st->isLiving() || st->coversPos(destinationTile)) //directly hit or alive
{ {

View File

@ -313,6 +313,13 @@ const std::string& CSpell::getIconImmune() const
return iconImmune; return iconImmune;
} }
const std::string& CSpell::getCastSound() const
{
return castSound;
}
si32 CSpell::getCost(const int skillLevel) const si32 CSpell::getCost(const int skillLevel) const
{ {
return costs[skillLevel]; return costs[skillLevel];
@ -693,11 +700,6 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode& json)
//by default all flags are set to false in constructor //by default all flags are set to false in constructor
if(flags["summoning"].Bool())
{
logGlobal->warnStream() << spell->name << ": summoning flag in unimplemented";
}
spell->isDamage = flags["damage"].Bool(); //do this before "offensive" spell->isDamage = flags["damage"].Bool(); //do this before "offensive"
if(flags["offensive"].Bool()) if(flags["offensive"].Bool())
@ -767,6 +769,16 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode& json)
const JsonNode & graphicsNode = json["graphics"]; const JsonNode & graphicsNode = json["graphics"];
spell->iconImmune = graphicsNode["iconImmune"].String(); spell->iconImmune = graphicsNode["iconImmune"].String();
spell->iconBook = graphicsNode["iconBook"].String();
spell->iconEffect = graphicsNode["iconEffect"].String();
spell->iconScenarioBonus = graphicsNode["iconScenarioBonus"].String();
spell->iconScroll = graphicsNode["iconScroll"].String();
const JsonNode & soundsNode = json["sounds"];
spell->castSound = soundsNode["cast"].String();
//load level attributes //load level attributes

View File

@ -103,6 +103,8 @@ public:
*/ */
const std::string& getIconImmune() const; const std::string& getIconImmune() const;
const std::string& getCastSound() const;
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & identifier & id & name & abbName & descriptions & level & earth & water & fire & air & power & costs h & identifier & id & name & abbName & descriptions & level & earth & water & fire & air & power & costs
@ -114,8 +116,12 @@ public:
h & absoluteImmunities & defaultProbability; h & absoluteImmunities & defaultProbability;
h & isSpecial; h & isSpecial;
h & castSound & iconBook & iconEffect & iconScenarioBonus & iconScroll ;
} }
friend class CSpellHandler; friend class CSpellHandler;
friend class Graphics;
private: private:
void setIsOffensive(const bool val); void setIsOffensive(const bool val);
@ -148,8 +154,13 @@ private:
std::string iconImmune; std::string iconImmune;
std::string iconBook;
std::string iconEffect;
std::string iconScenarioBonus;
std::string iconScroll;
///sound related stuff
std::string castSound;
}; };

View File

@ -28,7 +28,7 @@
#include "mapping/CCampaignHandler.h" //for CCampaignState #include "mapping/CCampaignHandler.h" //for CCampaignState
#include "rmg/CMapGenerator.h" // for CMapGenOptions #include "rmg/CMapGenerator.h" // for CMapGenOptions
const ui32 version = 746; const ui32 version = 747;
const ui32 minSupportedVersion = version; const ui32 minSupportedVersion = version;
class CConnection; class CConnection;

View File

@ -4127,7 +4127,8 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
++chainLightningModifier; ++chainLightningModifier;
} }
} }
else if (spell->hasEffects())
if (spell->hasEffects())
{ {
int stackSpellPower = 0; int stackSpellPower = 0;
if (stack && mode != ECastingMode::MAGIC_MIRROR) if (stack && mode != ECastingMode::MAGIC_MIRROR)
@ -4142,7 +4143,7 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
CStack::stackEffectToFeature(sse.effect, pseudoBonus); CStack::stackEffectToFeature(sse.effect, pseudoBonus);
if (spellID == SpellID::SHIELD || spellID == SpellID::AIR_SHIELD) if (spellID == SpellID::SHIELD || spellID == SpellID::AIR_SHIELD)
{ {
sse.effect.back().val = (100 - sse.effect.back().val); //fix to original config: shiled should display damage reduction sse.effect.back().val = (100 - sse.effect.back().val); //fix to original config: shield should display damage reduction
} }
if (spellID == SpellID::BIND && stack)//bind if (spellID == SpellID::BIND && stack)//bind
{ {
@ -4209,7 +4210,8 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
sendAndApply(&sse); sendAndApply(&sse);
} }
else if (spell->isRisingSpell() || spell->id == SpellID::CURE)
if (spell->isRisingSpell() || spell->id == SpellID::CURE)
{ {
int hpGained = 0; int hpGained = 0;
if (stack) if (stack)
@ -4275,7 +4277,7 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
sendAndApply(&bsr); sendAndApply(&bsr);
} }
} }
else
switch (spellID) switch (spellID)
{ {
case SpellID::QUICKSAND: case SpellID::QUICKSAND:
@ -4370,7 +4372,7 @@ void CGameHandler::handleSpellCasting( SpellID spellID, int spellLvl, BattleHex
if (!clonedStack) if (!clonedStack)
{ {
complain ("No target stack to clone!"); complain ("No target stack to clone!");
return; break;
} }
BattleStackAdded bsa; BattleStackAdded bsa;