Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Strange Error

A topic by TheAlCat created 32 days ago Views: 34 Replies: 4
Viewing posts 1 to 5

Instead of taking turns with the damage, for whatever reason, when a player  targets an enemy or the enemy targets a player, the damage is done all at once making the hp go down to zero and having multiple "failed" messages.

Version: IDE version 2024.13.1.193  Runtime version 2024.13.1.242

I'm not sure what is causing the problem but I haven't been able to eleminate the battle object, the gamedata script etc.

oBattle create event code:

instance_deactivate_all(true);

units = [];

turn = 0;

unitTurnOrder = [];

unitRenderOrder = [];

turnCount = 0;

roundCount = 0;

battleWaitTimeFrames = 30; 

battleWaitTimeRemaining = 0;

battleText = "";

currentUser = noone;

currentAction = -1;

currentTargets = noone;

//Make targetting cursor

cursor =

{

activeUser : noone,

activeTarget : noone,

activeAction : -1,

targetSide : -1,

targetIndex : 0,

targetAll : false,

confirmDelay : 0,

active : false

};

//Make enemies

for (var i = 0; i < array_length(enemies); i++)

{

enemyUnits[i] = instance_create_depth(x+250+(i*10),y+68+(i*20),depth-10,oBattleUnitEnemy, enemies[i])

array_push(units, enemyUnits[i]);

}

//Make party

for (var i = 0; i < array_length(global.party); i++)

{

partyUnits[i] = instance_create_depth(x+70+(i*10),y+68+(i*15),depth-10,oBattleUnitPC, global.party[i])

array_push(units, partyUnits[i]);

}

//Shuffle turn order

unitTurnOrder = array_shuffle(units);

//Get render order

RefreshRenderOrder = function()

{

unitRenderOrder = [];

array_copy(unitRenderOrder,0,units,0,array_length(units));

array_sort(unitRenderOrder,function(_1, _2)

{

return _1.y - _2.y;

});

}

RefreshRenderOrder();

function BattleStateSelectAction()

{   

if (!instance_exists(oMenu))

{

//Get current unit

var _unit = unitTurnOrder[turn];

//is the unit dead or unable to act?

if (!instance_exists(_unit)) or (_unit.hp <= 0)

{

battleState = BattleStateVictoryCheck;

exit;

}

//Select an action to perform

//BeginAction(_unit.id, global.actionLibrary.attack, _unit.id);

//if unit is player controlled:

if (_unit.object_index == oBattleUnitPC)

{

//Compile the action menu

var _menuOptions = [];

var _subMenus = {};

var _actionList = _unit.actions;

for (var i = 0; i < array_length(_actionList); i++)

{

var _action = _actionList[i];

var _available = true; //later we will replace this to check mp.

var _nameAndCount = _action.name; //later we will replace this

if (_action.subMenu == -1)

{

array_push(_menuOptions, [_nameAndCount, MenuSelectAction, [_unit, _action],_available]);

}

else

{

//create or add to a submenu

if (is_undefined(_subMenus[$ _action.subMenu]))

{

variable_struct_set(_subMenus, _action.subMenu,[[_nameAndCount,MenuSelectAction,[_unit,_action],_available]]);

}

else

{

array_push(_subMenus[$ _action.subMenu], [_nameAndCount, MenuSelectAction, [_unit, _action], _available]);

}

}

}

//turn sub menus into an array

var _subMenusArray = variable_struct_get_names(_subMenus);

for (var i = 0; i < array_length(_subMenusArray); i++)

{

//sort submenus if needed

//(here)

//add back option at the end of each submenu

//array_push(_subMenus[$ _subMenusArray[i]], ["Back", MenuGoBack -1, true]);

if (_action.subMenu == -1) array_push(_subMenus[$ _subMenusArray[i]], ["Back", MenuGoBack -1, true]);

//add submenu into main menu

//array_push(_menuOptions,[_subMenusArray[i], SubMenu, [_subMenus[$ _subMenusArray[i]]],true]);

if (_action.subMenu == -1) array_push(_menuOptions,[_nameAndCount, MenuSelectAction, [_unit, _action], _available]);

}

Menu(x+10, y+110, _menuOptions, , 74, 60)

}

else

{

//if unit is AI controlled:

var _enemyAction = _unit.AIscript();

if (_enemyAction != -1) BeginAction(_unit.id, _enemyAction[0], _enemyAction[1]);

}

  }

}

function BeginAction(_user, _action, _targets)

{

currentUser = _user;

currentAction = _action;

currentTargets = _targets;

battleText = string_ext(_action.description,[_user.name]);

if (!is_array(currentTargets)) currentTargets = [currentTargets];

battleWaitTimeRemaining = battleWaitTimeFrames;

with (_user)

{

acting = true;

//play user animation if it is defined for that action and that user

if (!is_undefined(_action[$ "userAnimation"])) and (!is_undefined(_user.sprites[$ _action.userAnimation]))

{

sprite_index = sprites[$ _action.userAnimation];

image_index = 0;

}

}

battleState = BattleStatePerformAction;

}

function BattleStatePerformAction()

{

//if animation etc is still playing

if (currentUser.acting)

{

//when it ends, perform action effect if it exists

if (currentUser.image_index >= currentUser.image_number -1)

{

with (currentUser)

{

sprite_index = sprites.idle;

image_index = 0;

acting = false;

}

if (variable_struct_exists(currentAction, "effectSprite"))

{

if (currentAction.effectOnTarget == MODE.ALWAYS) or ( (currentAction.effectOnTarget == MODE.VARIES) and (array_length(currentTargets) <= 1) )

for (var i = 0; i < array_length(currentTargets); i++)

{

instance_create_depth(currentTargets[i].x,currentTargets[i].y,currentTargets[i].depth-1,oBattleEffect,{sprite_index : currentAction.effectSprite})

}

}

else //play at 0,0

{

var _effectSprite = currentAction.effectSprite

if (variable_struct_exists(currentAction,"effectSpriteNoTarget")) _effectSprite = currentAction.effectSpriteNoTarget;

instance_create_depth(x,y,depth-100,oBattleEffect,{sprite_index : _effectSprite});

}

}

currentAction.func(currentUser, currentTargets);

}

else //wait for delay and then end the turn

   if (!instance_exists(oBattleEffect))

   {

   battleWaitTimeRemaining--

   if (battleWaitTimeRemaining == 0)

   {

   battleState = BattleStateVictoryCheck;

   }

   }

}

}

function BattleStateVictoryCheck()

{

battleState = BattleStateTurnProgression;

}

function BattleStateTurnProgression()

{

battleText = ""; //reset battle text

turnCount++; //total turns

turn++;

//Loop turns

if (turn > array_length(unitTurnOrder) - 1)

{

turn = 0;

roundCount++;

}

battleState = BattleStateSelectAction;

}

battleState = BattleStateSelectAction;

oBattle step event code:

battleState();

//Cursor control

if (cursor.active)

{

with (cursor)

{

//input

var _keyUp = keyboard_check_pressed(vk_up);

var _keyDown = keyboard_check_pressed(vk_down);

var _keyLeft = keyboard_check_pressed(vk_left);

var _keyRight = keyboard_check_pressed(vk_right);

var _keyToggle = false;

var _keyConfirm = false;

var _keyCancel = false;

confirmDelay++

if (confirmDelay > 1)

{

_keyConfirm = keyboard_check_pressed(vk_enter);

_keyCancel = keyboard_check_pressed(vk_escape);

_keyToggle = keyboard_check_pressed(vk_shift);

}

var _moveH = _keyRight - _keyLeft;

var _moveV = _keyDown - _keyUp;

if (_moveH == -1) targetSide = oBattle.partyUnits;

if (_moveH == 1) targetSide = oBattle.enemyUnits;

//verify target list

if (targetSide == oBattle.enemyUnits)

{

targetSide = array_filter(targetSide, function(_element, _index)

{

return _element.hp > 0;

});

}

//move between targets

if (targetAll == false) //Single target mode

{

if (_moveV == 1) targetIndex++;

if (_moveV == -1) targetIndex--;

//wrap

var _targets = array_length(targetSide);

if (targetIndex < 0) targetIndex = _targets - 1;

if (targetIndex > (_targets - 1)) targetIndex = 0;

//identify target

activeTarget = targetSide[targetIndex];

//toggle all mode

if (activeAction.targetAll == MODE.VARIES) and (_keyToggle) //switch to all mode

{

targetAll = true;

}

}

else //target all mode

{

activeTarget = targetSide;

if (activeAction.targetAll == MODE.VARIES) and (_keyToggle) //switch to single mode

{

targetAll = false;

}

}

//Confirm action

if (_keyConfirm)

{

with (oBattle) BeginAction(cursor.activeUser, cursor.activeAction, cursor.activeTarget);

with (oMenu) instance_destroy();

active = false;

confirmDelay = 0;

}

//Cancel and return to menu

if (_keyCancel) and (!_keyConfirm)

{

with (oMenu) active = true;

active = false;

confirmDelay = 0;

}

}

}

Battle Functions code:

function NewEncounter(_enemies, _bg)

{

instance_create_depth

(

camera_get_view_x(view_camera[0]),

camera_get_view_y(view_camera[0]),

-9999,

oBattle,

{enemies: _enemies, creator: id, battleBackground: _bg}

);

}

function BattleChangeHP(_target, _amount, _AliveDeadOrEither = 0)

{

//_AliveDeadOrEither: 0 = alive only, 1 = dead only, 2 = any

var _failed = false;

if (_AliveDeadOrEither == 0) and (_target.hp <= 0) _failed = true;

if (_AliveDeadOrEither == 1) and (_target.hp > 0) _failed = true;

var _col = c_white;

if (_amount > 0) _col = c_lime;

if (_failed)

{

_col = c_white;

_amount = "failed";

}

instance_create_depth

(

_target.x,

_target.y,

_target.depth-1,

oBattleFloatingText,

{font : fnM5x7, col: _col, text : string(_amount)}

);

if (!_failed) _target.hp = clamp(_target.hp + _amount, 0, _target.hpMax);

}

Game data code:

//Action Library

global.actionLibrary =

{

   attack :

   {

   name : "Attack",

   description : "{0} attacks!",

   subMenu : -1,

   targetRequired : true,

   targetEnemyByDefault : true,

   targetAll : MODE.NEVER,

   userAnimation : "attack",

   effectSprite : sAttackBonk,

   effectOnTarget : MODE.ALWAYS,

   func : function(_user, _targets)

   {

   var _damage = ceil(_user.strength + random_range(-_user.strength * 0.25, _user.strength * 0.25));

   BattleChangeHP(_targets[0],-_damage,0);

   }

   },

   ice :

   {

   name : "Ice",

   description : "{0} casts Ice!",

   subMenu : "Magic",

   mpCost : 4,

   targetRequired : true,

   targetEnemyByDefault : true, //0: party/self, 1: enemy

   targetAll : MODE.VARIES,

   userAnimation : "cast",

   effectSprite : sAttackIce,

   effectOnTarget : MODE.ALWAYS,

   func : function(_user, _targets)

   {

   var _damage = irandom_range(10,15);

   BattleChangeHP(_targets[0],-_damage,);

   //BattleChangeMP(_user, -mpCost);

   }

   }

}

enum MODE

{

NEVER = 0,

ALWAYS = 1,

VARIES = 2

}

//Party data

global.party = 

[

{

name: "Lulu",

hp: 89,

hpMax: 89,

mp: 15,

mpMax: 15,

strength: 6,

sprites : { idle: sLuluIdle, attack: sLuluAttack, defend: sLuluDefend, down: sLuluDown},

actions : [global.actionLibrary.attack]

}

,

{

name: "Questy",

hp: 44,

hpMax: 44,

mp: 30,

mpMax: 30,

strength: 4,

sprites : { idle: sQuestyIdle, attack: sQuestyCast, cast: sQuestyCast, down: sQuestyDown},

actions : [global.actionLibrary.attack, global.actionLibrary.ice]

}

]

//Enemy Data

global.enemies =

{

slimeG: 

{

name: "Slime",

hp: 30,

hpMax: 30,

mp: 0,

mpMax: 0,

strength: 5,

sprites: { idle: sSlime, attack: sSlimeAttack},

actions: [global.actionLibrary.attack],

xpValue : 15,

AIscript : function()

{

//attack random party member

var _action = actions[0];

var _possibleTargets = array_filter(oBattle.partyUnits, function(_unit, _index)

{

return (_unit.hp > 0);

});

var _target = _possibleTargets[irandom(array_length(_possibleTargets)-1)];

return [_action, _target];

}

}

,

bat: 

{

name: "Bat",

hp: 15,

hpMax: 15,

mp: 0,

mpMax: 0,

strength: 4,

sprites: { idle: sBat, attack: sBatAttack},

actions: [global.actionLibrary.attack],

xpValue : 18,

AIscript : function()

{

//attack random party member

var _action = actions[0];

var _possibleTargets = array_filter(oBattle.partyUnits, function(_unit, _index)

{

return (_unit.hp > 0);

});

var _target = _possibleTargets[irandom(array_length(_possibleTargets)-1)];

return [_action, _target];

}

}

}