Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 66 additions & 43 deletions src/magic/castSpell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,39 @@ void castSpellInit(Uint32 caster_uid, spell_t* spell)
return;
}

// Check to make sure the Caster is not swimming
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a lot of conditions here which are duplicated (not only in here but in actplayer.cpp, acthudweapon.cpp, which should probably be factored out to reduce the duplication and the amount of code that needs to be changed should additional conditions for swimming be added.

// If the Caster is not a Magic Trap, they could potentially be in a water tile
// TODO: Currently only Players can swim, this must be expanded if that changes (caster->behavior != &actMagicTrap)
if ( player >= 0 ) // TODOR: Bad check, ambiguious
{
bool bIsCasterLevitating = isLevitating(stat); // If levitating, they can cast
bool bIsCasterWaterWalking = false; // If water walking, they can cast

if ( stat->shoes != nullptr )
{
if ( stat->shoes->type == IRON_BOOTS_WATERWALKING )
{
bIsCasterWaterWalking = true;
}
}

// If both cases are false, the Caster could potentially be swimming
if ( bIsCasterLevitating != true && bIsCasterWaterWalking != true )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!= true is redundant on bools :)

{
if ( players[player] && players[player]->entity )
{
int x = std::min<int>(std::max<int>(0, floor(caster->x / 16)), map.width - 1);
int y = std::min<int>(std::max<int>(0, floor(caster->y / 16)), map.height - 1);
if ( animatedtiles[map.tiles[y * MAPLAYERS + x * MAPLAYERS * map.height]] )
{
// The Caster is in a water tile, so must be swimming
messagePlayer(player, language[410]); // "Cannot cast spells while swimming!"
return;
}
}
}
}

if ( stat->EFFECTS[EFF_PARALYZED] )
{
return;
Expand Down Expand Up @@ -204,6 +237,39 @@ Entity* castSpell(Uint32 caster_uid, spell_t* spell, bool using_magicstaff, bool
}
}

// Check to make sure the Caster did not start swimming after starting the cast
// If the Caster is not a Magic Trap, they could potentially be in a water tile
// TODO: Currently only Players can swim, this must be expanded if that changes (caster->behavior != &actMagicTrap)
if ( player >= 0 ) // TODOR: Bad check, ambiguious
{
bool bIsCasterLevitating = isLevitating(stat); // If levitating, they can cast
bool bIsCasterWaterWalking = false; // If water walking, they can cast

if ( stat->shoes != nullptr )
{
if ( stat->shoes->type == IRON_BOOTS_WATERWALKING )
{
bIsCasterWaterWalking = true;
}
}

// If both cases are false, the Caster could potentially be swimming
if ( bIsCasterLevitating != true && bIsCasterWaterWalking != true )
{
if ( players[player] && players[player]->entity )
{
int x = std::min<int>(std::max<int>(0, floor(caster->x / 16)), map.width - 1);
int y = std::min<int>(std::max<int>(0, floor(caster->y / 16)), map.height - 1);
if ( animatedtiles[map.tiles[y * MAPLAYERS + x * MAPLAYERS * map.height]] )
{
// The Caster is in a water tile, so must be swimming
messagePlayer(player, language[410]); // "Cannot cast spells while swimming!"
return nullptr;
}
}
}
}

bool newbie = false;
if ( !using_magicstaff && !trap)
{
Expand Down Expand Up @@ -261,49 +327,6 @@ Entity* castSpell(Uint32 caster_uid, spell_t* spell, bool using_magicstaff, bool
}
}

//Check if the bugger is levitating.
bool levitating = false;
if (!trap)
{
levitating = isLevitating(stat);
}

//Water walking boots
bool waterwalkingboots = false;
if (!trap)
{
if (stat->shoes != NULL)
if (stat->shoes->type == IRON_BOOTS_WATERWALKING )
{
waterwalkingboots = true;
}
}

node_t* node2; //For traversing the map looking for...liquids?
//Check if swimming.
if (!waterwalkingboots && !levitating && !trap && player >= 0)
{
bool swimming = false;
if (players[player] && players[player]->entity)
{
int x = std::min<int>(std::max<int>(0, floor(caster->x / 16)), map.width - 1);
int y = std::min<int>(std::max<int>(0, floor(caster->y / 16)), map.height - 1);
if (animatedtiles[map.tiles[y * MAPLAYERS + x * MAPLAYERS * map.height]])
{
swimming = true;
}
}
if (swimming)
{
//Can't cast spells while swimming if not levitating or water walking.
if (player >= 0)
{
messagePlayer(player, language[410]);
}
return nullptr;
}
}

//Right. First, grab the root element, which is what determines the delivery system.
//spellElement_t *element = (spellElement_t *)spell->elements->first->element;
spellElement_t* element = (spellElement_t*)node->element;
Expand Down