Permalink
Browse files

Implemented the stun effect.

Also mde the status effects timers update only when the battle isn't
waiting for the player to be a little bit more fair.

By avoiding to use the StunTimer() function, I also was able
to get rid of the BattleTimer class which look useless to me,
and corner case-prone.

I also added a 'Zzz' icon displayed on top of the enemies
when they're stunned.

Note also that the stun effect can miss, separately from the
damage chances.
  • Loading branch information...
1 parent e443c9a commit 0e6c8aa3431501197c01b8f5bf2ee87d7f57ac90 Yohann Ferreira committed Oct 4, 2012
View
@@ -428,6 +428,7 @@ status_effects[hoa_global.GameGlobal.GLOBAL_STATUS_AGILITY_RAISE] = {
end
end,
+ -- Note: This modifies the actor's idle state wait time accordingly.
Remove = function(effect)
effect:GetAffectedActor():ResetAgility();
end,
@@ -454,8 +455,8 @@ status_effects[hoa_global.GameGlobal.GLOBAL_STATUS_AGILITY_RAISE] = {
print("Lua warning: status effect had an invalid intensity value: " .. intensity);
end
- actor:SetStrength(base_value * attribute_modifier);
- -- TODO: Need to modify actor's idle state wait time accordingly here
+ -- Note: This modifies the actor's idle state wait time accordingly.
+ actor:SetAgility(base_value * attribute_modifier);
end
}
@@ -475,10 +476,12 @@ status_effects[hoa_global.GameGlobal.GLOBAL_STATUS_AGILITY_LOWER] = {
end
end,
+ -- Note: This modifies the actor's idle state wait time accordingly.
Remove = function(effect)
effect:GetAffectedActor():ResetAgility();
end,
+ -- Note: This modifies the actor's idle state wait time accordingly.
ModifyAttribute = function(effect)
actor = effect:GetAffectedActor();
intensity = effect:GetIntensity();
@@ -502,7 +505,6 @@ status_effects[hoa_global.GameGlobal.GLOBAL_STATUS_AGILITY_LOWER] = {
end
actor:SetAgility(base_value * attribute_modifier);
- -- TODO: Need to modify actor's idle state wait time accordingly here
end
}
@@ -684,20 +686,17 @@ status_effects[hoa_global.GameGlobal.GLOBAL_STATUS_PARALYSIS] = {
opposite_effect = hoa_global.GameGlobal.GLOBAL_STATUS_INVALID,
Apply = function(effect)
- -- TODO: Implement paralysis
battle_actor = effect:GetAffectedActor();
- --battle_actor:RegisterParalysis();
- print("Paralysis not implemented yet!!");
+ battle_actor:SetStunned(true);
end,
Update = function(effect)
-- Nothing needs to be updated for this effect
end,
Remove = function(effect)
- -- TODO: Implement paralysis
battle_actor = effect:GetAffectedActor();
- --battle_actor:UnregisterParalysis();
+ battle_actor:SetStunned(false);
end
}
View
@@ -96,20 +96,29 @@ skills[2] = {
skills[3] = {
name = hoa_system.Translate("Stun Strike"),
- description = hoa_system.Translate("A blow which targets vital areas and temporarily stun its target."),
+ description = hoa_system.Translate("A blow which temporarily stun its target."),
sp_required = 5,
warmup_time = 1200,
cooldown_time = 0,
action_name = "attack",
- target_type = hoa_global.GameGlobal.GLOBAL_TARGET_FOE,
+ target_type = hoa_global.GameGlobal.GLOBAL_TARGET_FOE_POINT,
BattleExecute = function(user, target)
target_actor = target:GetActor();
if (hoa_battle.CalculateStandardEvasionAdder(target, 5.5) == false) then
+ -- Calculate chance for paralysis effect and activate it
+ local attack_point = target_actor:GetAttackPoint(target:GetPoint());
+ local chance_modifier = (user:GetTotalMetaphysicalAttack() - attack_point:GetTotalMetaphysicalDefense()) * 3.0;
+ local chance = (hoa_utils.RandomFloat() * 100.0);
+ if (chance <= (50.0 + chance_modifier)) then
+ target_actor:RegisterStatusChange(hoa_global.GameGlobal.GLOBAL_STATUS_PARALYSIS, hoa_global.GameGlobal.GLOBAL_INTENSITY_POS_LESSER);
+ else
+ target_actor:RegisterMiss(true);
+ end
+
+ -- The damages are applied after the potential effects, so that a potential target death handles the effect removal properly
target_actor:RegisterDamage(hoa_battle.CalculatePhysicalDamage(user, target));
- -- TODO: Calculate chance for paralysis effect and activate it
- target_actor:RegisterStatusChange(hoa_global.GameGlobal.GLOBAL_STATUS_PARALYSIS, hoa_global.GameGlobal.GLOBAL_INTENSITY_POS_LESSER);
AudioManager:PlaySound("snd/swordslice1.wav");
else
target_actor:RegisterMiss(true);
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -360,40 +360,41 @@ class GlobalActor {
**/
//@{
void SetExperienceLevel(uint32 xp_level)
- { _experience_level = xp_level; }
+ { _experience_level = xp_level; }
void SetExperiencePoints(uint32 xp_points)
- { _experience_points = xp_points; }
+ { _experience_points = xp_points; }
void SetHitPoints(uint32 hp)
- { if (hp > _max_hit_points) _hit_points = _max_hit_points; else _hit_points = hp; }
+ { if (hp > _max_hit_points) _hit_points = _max_hit_points; else _hit_points = hp; }
void SetMaxHitPoints(uint32 hp)
- { _max_hit_points = hp; if (_hit_points > _max_hit_points) _hit_points = _max_hit_points; }
+ { _max_hit_points = hp; if (_hit_points > _max_hit_points) _hit_points = _max_hit_points; }
void SetSkillPoints(uint32 sp)
- { if (sp > _max_skill_points) _skill_points = _max_skill_points; else _skill_points = sp; }
+ { if (sp > _max_skill_points) _skill_points = _max_skill_points; else _skill_points = sp; }
void SetMaxSkillPoints(uint32 sp)
- { _max_skill_points = sp; if (_skill_points > _max_skill_points) _skill_points = _max_skill_points; }
+ { _max_skill_points = sp; if (_skill_points > _max_skill_points) _skill_points = _max_skill_points; }
void SetStrength(uint32 st)
- { _strength = st; _CalculateAttackRatings(); }
+ { _strength = st; _CalculateAttackRatings(); }
void SetVigor(uint32 vi)
- { _vigor = vi; _CalculateAttackRatings(); }
+ { _vigor = vi; _CalculateAttackRatings(); }
void SetFortitude(uint32 fo)
- { _fortitude = fo; _CalculateDefenseRatings(); }
+ { _fortitude = fo; _CalculateDefenseRatings(); }
void SetProtection(uint32 pr)
- { _protection = pr; _CalculateDefenseRatings(); }
+ { _protection = pr; _CalculateDefenseRatings(); }
- void SetAgility(uint32 ag)
- { _agility = ag; }
+ //! Made virtual to permit Battle Actors to recompute the idle state time.
+ virtual void SetAgility(uint32 ag)
+ { _agility = ag; }
void SetEvade(float ev)
- { _evade = ev; _CalculateEvadeRatings(); }
+ { _evade = ev; _CalculateEvadeRatings(); }
//@}
/** \name Class member add and subtract functions
View
@@ -237,7 +237,6 @@ namespace hoa_battle {
class SkillAction;
class ItemAction;
- class BattleTimer;
class BattleTarget;
class BattleItem;
@@ -157,6 +157,10 @@ BattleMedia::BattleMedia() {
}
script_file.CloseTable();
}
+
+ // Load the stunned icon
+ if (!_stunned_icon.Load("img/icons/effects/zzz.png"))
+ IF_PRINT_WARNING(BATTLE_DEBUG) << "failed to load stunned icon" << std::endl;
}
@@ -114,6 +114,9 @@ class BattleMedia {
**/
hoa_video::StillImage* GetStatusIcon(hoa_global::GLOBAL_STATUS type, hoa_global::GLOBAL_INTENSITY intensity);
+ const hoa_video::StillImage& GetStunnedIcon()
+ { return _stunned_icon; }
+
// ---------- Public members
//! \brief The static background image to be used for the battle
@@ -207,6 +210,9 @@ class BattleMedia {
//! \brief Contains the entire set of status effect icons
std::vector<hoa_video::StillImage> _status_icons;
+
+ //! \brief An icon displayed above the character's head when it is stunned.
+ hoa_video::StillImage _stunned_icon;
}; // class BattleMedia
} // namespace private_battle
@@ -58,7 +58,8 @@ BattleActor::BattleActor(GlobalActor* actor) :
_action(NULL),
_execution_finished(false),
_idle_state_time(0),
- _shake_timer(0),
+ _hurt_timer(0),
+ _is_stunned(false),
_animation_timer(0),
_x_stamina_location(0.0f),
_y_stamina_location(0.0f),
@@ -204,31 +205,29 @@ void BattleActor::RegisterDamage(uint32 amount, BattleTarget* target) {
// Apply a stun to the actor timer depending on the amount of damage dealt
float damage_percent = static_cast<float>(amount) / static_cast<float>(GetMaxHitPoints());
- uint32 stun_time = 0;
+ uint32 hurt_time = 0;
if (damage_percent < 0.10f)
- stun_time = 250;
+ hurt_time = 250;
else if (damage_percent < 0.25f)
- stun_time = 500;
+ hurt_time = 500;
else if (damage_percent < 0.50f)
- stun_time = 750;
+ hurt_time = 750;
else // (damage_percent >= 0.50f)
- stun_time = 1000;
+ hurt_time = 1000;
// Make the stun effect disappear faster depending on the battle type,
// to not advantage the attacker.
BattleMode* BM = BattleMode::CurrentInstance();
if (BM->GetBattleType() == BATTLE_TYPE_SEMI_ACTIVE)
- stun_time /= BATTLE_SEMI_ACTIVE_FACTOR;
+ hurt_time /= BATTLE_SEMI_ACTIVE_FACTOR;
else if (BM->GetBattleType() == BATTLE_TYPE_WAIT)
- stun_time /= BATTLE_WAIT_FACTOR;
+ hurt_time /= BATTLE_WAIT_FACTOR;
else if (BM->GetBattleType() == BATTLE_TYPE_ACTIVE)
- stun_time /= BATTLE_ACTIVE_FACTOR;
+ hurt_time /= BATTLE_ACTIVE_FACTOR;
- _state_timer.StunTimer(stun_time);
// Run a shake effect for the same time.
- _shake_timer.Initialize(stun_time);
- _shake_timer.Run();
-
+ _hurt_timer.Initialize(hurt_time);
+ _hurt_timer.Run();
// If the damage dealt was to a point target type, check for and apply any status effects triggered by this point hit
if ((target != NULL) && (IsTargetPoint(target->GetType()) == true)) {
@@ -311,16 +310,25 @@ void BattleActor::RegisterStatusChange(GLOBAL_STATUS status, GLOBAL_INTENSITY in
void BattleActor::Update() {
// Don't update the state timer when the battle tells is to pause
// when in idle state.
- if (!BattleMode::CurrentInstance()->AreActorStatesPaused())
- _state_timer.Update();
+ // Also don't elapse the status effect time when paused.
+ if (!BattleMode::CurrentInstance()->AreActorStatesPaused()) {
+ // Don't update the state_timer if the character is hurt.
+ if (!_hurt_timer.IsRunning()) {
+
+ // Check the stun effect when in idle state.
+ if (_state != ACTOR_STATE_IDLE || !_is_stunned)
+ _state_timer.Update();
+ }
+
+ _effects_supervisor->Update();
+ }
// Ths shaking updates even in pause mode, so that the shaking
// doesn't last indefinitely in that state.
- _shake_timer.Update();
+ _hurt_timer.Update();
_UpdateStaminaIconPosition();
- _effects_supervisor->Update();
_indicator_supervisor->Update();
if (_state_timer.IsFinished() == true) {
@@ -388,9 +396,8 @@ void BattleActor::_UpdateStaminaIconPosition() {
}
// Add a shake effect when the battle actor has received damages
- if (_shake_timer.IsRunning()) {
+ if (_hurt_timer.IsRunning())
x_pos += RandomFloat(-4.0f, 4.0f);
- }
_x_stamina_location = x_pos;
_y_stamina_location = y_pos;
@@ -601,9 +608,8 @@ void BattleCharacter::Update() {
}
// Add a shake effect when the battle actor has received damages
- if (_shake_timer.IsRunning()) {
+ if (_hurt_timer.IsRunning())
_x_location = _x_origin + RandomFloat(-6.0f, 6.0f);
- }
// If the character has finished to execute its battle action,
if (_state == ACTOR_STATE_ACTING && _state_timer.IsFinished()) {
@@ -626,6 +632,11 @@ void BattleCharacter::Update() {
void BattleCharacter::DrawSprite() {
VideoManager->Move(_x_location, _y_location);
_global_character->RetrieveBattleAnimation(_sprite_animation_alias)->Draw();
+
+ if (_is_stunned && _state == ACTOR_STATE_IDLE) {
+ VideoManager->MoveRelative(0, GetSpriteHeight());
+ BattleMode::CurrentInstance()->GetMedia().GetStunnedIcon().Draw();
+ }
} // void BattleCharacter::DrawSprite()
void BattleCharacter::ChangeSpriteAnimation(const std::string& alias) {
@@ -895,7 +906,7 @@ void BattleEnemy::Update() {
}
// Add a shake effect when the battle actor has received damages
- if (_shake_timer.IsRunning())
+ if (_hurt_timer.IsRunning())
_x_location += RandomFloat(-2.0f, 2.0f);
if (_state == ACTOR_STATE_ACTING) {
@@ -911,16 +922,14 @@ void BattleEnemy::Update() {
}
void BattleEnemy::DrawSprite() {
- VideoManager->Move(_x_location, _y_location);
-
- std::vector<StillImage>& sprite_frames = *(_global_enemy->GetBattleSpriteFrames());
-
// Dead enemies are gone from screen.
if (_state == ACTOR_STATE_DEAD)
return;
+ std::vector<StillImage>& sprite_frames = *(_global_enemy->GetBattleSpriteFrames());
float hp_percent = static_cast<float>(GetHitPoints()) / static_cast<float>(GetMaxHitPoints());
+ VideoManager->Move(_x_location, _y_location);
// Alpha will range from 1.0 to 0.0 in the following calculations
if (_state == ACTOR_STATE_DYING) {
sprite_frames[3].Draw(Color(1.0f, 1.0f, 1.0f, _sprite_alpha));
@@ -943,6 +952,11 @@ void BattleEnemy::DrawSprite() {
float alpha = 1.0f - (hp_percent * 3.0f);
sprite_frames[3].Draw(Color(1.0f, 1.0f, 1.0f, alpha));
}
+
+ if (_is_stunned && _state == ACTOR_STATE_IDLE) {
+ VideoManager->MoveRelative(0, GetSpriteHeight());
+ BattleMode::CurrentInstance()->GetMedia().GetStunnedIcon().Draw();
+ }
} // void BattleEnemy::DrawSprite()
void BattleEnemy::_DecideAction() {
@@ -303,6 +303,11 @@ class BattleActor : public hoa_global::GlobalActor, public BattleObject {
**/
void ChangeSkillPoints(int32 amount);
+ //! \brief Stuns the BattleActor, preventing its state timer to update.
+ //! \param stun Whether the actor should be stunned.
+ void SetStunned(bool stun)
+ { _is_stunned = stun; }
+
/** \brief Updates the state of the actor
***
*** The optional boolean parameter is primarily used by battle sequences which desire to update the sprite graphics
@@ -398,7 +403,7 @@ class BattleActor : public hoa_global::GlobalActor, public BattleObject {
hoa_video::StillImage& GetStaminaIcon()
{ return _stamina_icon; }
- BattleTimer& GetStateTimer()
+ hoa_system::SystemTimer& GetStateTimer()
{ return _state_timer; }
//! \note If the actor is in the idle state, this will not affect the state timer
@@ -426,18 +431,17 @@ class BattleActor : public hoa_global::GlobalActor, public BattleObject {
uint32 _idle_state_time;
//! \brief A timer used as the character progresses through the standard series of actor states
- BattleTimer _state_timer;
+ hoa_system::SystemTimer _state_timer;
+
+ //! \brief A timer telling the time the character is hurt, making it visually shaking.
+ hoa_system::SystemTimer _hurt_timer;
- //! \brief A timer telling the time the character will be visually shaking.
- hoa_system::SystemTimer _shake_timer;
+ //! \brief Tells whether the actor is stunned, preventing its idle state time to update.
+ bool _is_stunned;
//! \brief Used to assist in the animation of actors as they move on the battlefield
hoa_system::SystemTimer _animation_timer;
- // TODO: add later for effects such as "petrify"
-// //! \brief When set to true, the actor essentially has immunity and can not be targeted by attacks
-// bool _not_targetable;
-
//! \brief The x and y coordinates of the actor's current stamina icon on the stamina bar.
float _x_stamina_location, _y_stamina_location;
Oops, something went wrong.

0 comments on commit 0e6c8aa

Please sign in to comment.