Skip to content

Commit 53e5e98

Browse files
committed
updated task clearing, removed player bitmap from boss check, streamlined ability task checks
1 parent 53e5a0b commit 53e5e98

3 files changed

Lines changed: 122 additions & 100 deletions

File tree

src/battle-nads/Character.sol

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -342,20 +342,38 @@ abstract contract Character is Abilities {
342342
combatant.tracker.updateActiveTask = false;
343343
}
344344
}
345-
combatant = _checkClearAbility(combatant);
345+
combatant = _checkClearAbility(combatant, true);
346346
return combatant;
347347
}
348348

349-
function _checkClearAbility(BattleNad memory combatant) internal returns (BattleNad memory) {
349+
function _checkClearAbility(BattleNad memory combatant, bool forceClear) internal returns (BattleNad memory) {
350+
// load if not loaded
351+
if (combatant.activeAbility.taskAddress == address(0)) {
352+
combatant.activeAbility = _loadAbility(combatant.id);
353+
}
350354
if (
351355
_isValidAddress(combatant.activeAbility.taskAddress) || combatant.activeAbility.targetBlock > 0
352356
|| combatant.activeAbility.stage > 0
353357
) {
354-
combatant.activeAbility.taskAddress = _EMPTY_ADDRESS;
355-
combatant.activeAbility.targetBlock = uint64(0);
356-
combatant.activeAbility.stage = 0;
357-
combatant.activeAbility.ability = Ability.None;
358-
_clearAbility(combatant.id);
358+
if (forceClear) {
359+
combatant.activeAbility.taskAddress = _EMPTY_ADDRESS;
360+
combatant.activeAbility.targetBlock = uint64(0);
361+
combatant.activeAbility.stage = 0;
362+
combatant.activeAbility.ability = Ability.None;
363+
combatant.tracker.updateActiveAbility = false;
364+
_clearAbility(combatant.id);
365+
return combatant;
366+
}
367+
368+
(address underlyingMsgSender, bool isTask) = _loadUnderlyingSenderData();
369+
if (isTask && underlyingMsgSender == combatant.activeAbility.taskAddress) {
370+
combatant.activeAbility.taskAddress = _EMPTY_ADDRESS;
371+
combatant.activeAbility.targetBlock = uint64(0);
372+
combatant.activeAbility.stage = 0;
373+
combatant.activeAbility.ability = Ability.None;
374+
combatant.tracker.updateActiveAbility = false;
375+
_clearAbility(combatant.id);
376+
}
359377
}
360378
return combatant;
361379
}

src/battle-nads/Handler.sol

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -507,10 +507,6 @@ abstract contract Handler is Balances {
507507

508508
// CASE: No combatants remain
509509
if (!attacker.isInCombat()) {
510-
//if (!attacker.isMonster()) {
511-
// attacker = _checkClearAbility(attacker);
512-
//}
513-
514510
reschedule = false;
515511
nextExecutionBlock = 0;
516512

@@ -624,13 +620,11 @@ abstract contract Handler is Balances {
624620
if (reschedule) {
625621
(attacker, reschedule) = _createOrRescheduleAbilityTask(attacker, nextBlock);
626622
if (!reschedule) {
627-
attacker = _checkClearAbility(attacker);
628623
revert Errors.TaskNotRescheduled();
629624
}
630625
} else {
631-
attacker = _checkClearAbility(attacker);
626+
attacker = _checkClearAbility(attacker, true);
632627
}
633-
634628
return attacker;
635629
}
636630

@@ -671,11 +665,10 @@ abstract contract Handler is Balances {
671665
if (reschedule) {
672666
(attacker, reschedule) = _createOrRescheduleAbilityTask(attacker, nextBlock);
673667
if (!reschedule) {
674-
// revert Errors.TaskNotRescheduled();
675-
attacker = _checkClearAbility(attacker);
668+
revert Errors.TaskNotRescheduled();
676669
}
677670
} else {
678-
attacker = _checkClearAbility(attacker);
671+
attacker = _checkClearAbility(attacker, true);
679672
}
680673

681674
return attacker;
@@ -687,7 +680,7 @@ abstract contract Handler is Balances {
687680
{
688681
// Verify that attacker is still alive
689682
if (attacker.isDead()) {
690-
attacker = _checkClearAbility(attacker);
683+
attacker = _checkClearAbility(attacker, true);
691684
// Process death in combat task
692685
return (attacker, false, 0);
693686
}

src/battle-nads/TaskHandler.sol

Lines changed: 93 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,11 @@ contract TaskHandler is Handler, GeneralReschedulingTask {
185185
if (reschedule) {
186186
(attacker, reschedule) = _createOrRescheduleAbilityTask(attacker, targetBlock);
187187
if (!reschedule) {
188-
attacker = _checkClearAbility(attacker);
188+
attacker = _checkClearAbility(attacker, !attacker.isInCombat());
189189
emit Events.TaskNotScheduledInTaskHandler(22, attacker.id, block.number, targetBlock);
190190
}
191191
} else {
192-
attacker = _checkClearAbility(attacker);
192+
attacker = _checkClearAbility(attacker, !attacker.isInCombat());
193193
}
194194

195195
// If successful, store the data
@@ -366,11 +366,7 @@ contract TaskHandler is Handler, GeneralReschedulingTask {
366366

367367
if (combatant.isMonster() && !_isValidAddress(combatant.owner)) {
368368
_clearActiveTask(combatant.id);
369-
370-
AbilityTracker memory activeAbility = _loadAbility(combatant.id);
371-
if (_isValidAddress(activeAbility.taskAddress)) {
372-
combatant = _checkClearAbility(combatant);
373-
}
369+
combatant = _checkClearAbility(combatant, true);
374370

375371
return combatant;
376372
}
@@ -394,7 +390,7 @@ contract TaskHandler is Handler, GeneralReschedulingTask {
394390
AbilityTracker memory activeAbility = _loadAbility(combatant.id);
395391
if (_isValidAddress(activeAbility.taskAddress)) {
396392
SessionKey memory key = _loadSessionKey(activeAbility.taskAddress);
397-
combatant = _checkClearAbility(combatant);
393+
combatant = _checkClearAbility(combatant, true);
398394
if (combatant.owner == key.owner && key.expiration > 0 && key.isTask) {
399395
_deactivateSessionKey(activeAbility.taskAddress);
400396
}
@@ -431,96 +427,111 @@ contract TaskHandler is Handler, GeneralReschedulingTask {
431427
}
432428

433429
uint64 activeBlock = uint64(_loadBal.activeBlockMedium);
434-
435-
/*
436-
if (!combatant.isMonster()) {
437-
if (!_isValidAddress(combatant.activeAbility.taskAddress)) {
438-
combatant.activeAbility = _loadAbility(combatant.id);
439-
}
440-
441-
if (_isValidAddress(combatant.activeAbility.taskAddress)) {
442-
if (underlyingMsgSender != combatant.activeAbility.taskAddress) {
443-
SessionKey memory key = _loadSessionKey(combatant.activeAbility.taskAddress);
444-
if (key.expiration <= block.number) {
445-
combatant = _checkClearAbility(combatant);
446-
if (combatant.owner == key.owner && key.expiration > 0 && key.isTask) {
447-
_deactivateSessionKey(combatant.activeAbility.taskAddress);
448-
}
449-
} else if (activeBlock > combatant.activeAbility.targetBlock) {
450-
combatant = _checkClearAbility(combatant);
451-
if (combatant.owner == key.owner && key.expiration > 0 && key.isTask) {
452-
_deactivateSessionKey(combatant.activeAbility.taskAddress);
453-
}
454-
}
455-
}
456-
}
457-
}
458-
*/
459-
460-
if (_isValidAddress(combatant.activeTask.taskAddress)) {
461-
if (underlyingMsgSender != combatant.activeTask.taskAddress) {
462-
SessionKey memory key = _loadSessionKey(combatant.activeTask.taskAddress);
463-
if (key.expiration <= block.number) {
464-
combatant = _checkClearAbility(combatant);
465-
if (combatant.owner == key.owner && key.expiration > 0 && key.isTask) {
466-
_deactivateSessionKey(combatant.activeTask.taskAddress);
467-
}
468-
} else if (activeBlock > combatant.activeTask.targetBlock) {
469-
combatant = _checkClearAbility(combatant);
470-
if (combatant.owner == key.owner && key.expiration > 0 && key.isTask) {
471-
_deactivateSessionKey(combatant.activeTask.taskAddress);
472-
}
473-
}
474-
}
475-
return (combatant, true, combatant.activeTask.taskAddress);
476-
}
477-
478430
bytes32 taskID = _loadActiveTaskID(combatant.id);
479-
uint64 targetBlock = uint64(uint256(taskID) >> 160);
480431

481432
if (!_isValidID(taskID)) {
482433
return (combatant, hasActiveCombatTask, activeTask);
483434
}
484435

436+
uint64 targetBlock = uint64(uint256(taskID) >> 160);
485437
activeTask = address(uint160(uint256(taskID)));
486438

487-
if (isTask && _abstractedMsgSender() == combatant.owner) {
488-
SessionKey memory key = _loadSessionKey(activeTask);
489-
if (key.owner == combatant.owner && underlyingMsgSender == combatant.activeTask.taskAddress) {
490-
if (key.expiration > block.number) {
491-
combatant.activeTask.taskAddress = underlyingMsgSender;
492-
return (combatant, true, underlyingMsgSender);
493-
} else {
494-
return (combatant, false, _EMPTY_ADDRESS);
495-
}
496-
}
439+
if (combatant.activeTask.taskAddress == address(0)) {
440+
combatant.activeTask.taskAddress = activeTask;
441+
} else if (activeTask != combatant.activeTask.taskAddress) {
442+
// Signals that this has already been changed - for edge cases, should not be reachable in prod
443+
return (combatant, true, activeTask);
497444
}
498445

499-
if (_isValidAddress(activeTask)) {
500-
SessionKey memory key = _loadSessionKey(activeTask);
501-
if (combatant.owner != key.owner) {
502-
_deactivateSessionKey(activeTask);
503-
_clearActiveTask(combatant.id);
504-
activeTask = _EMPTY_ADDRESS;
505-
} else if (!isTask) {
506-
if (activeBlock > targetBlock) {
507-
_clearActiveTask(combatant.id);
508-
if (combatant.owner == key.owner && key.expiration > 0 && key.isTask) {
509-
_deactivateSessionKey(activeTask);
446+
if (combatant.activeTask.targetBlock == 0) {
447+
combatant.activeTask.targetBlock = targetBlock;
448+
}
449+
450+
if (!_isValidAddress(combatant.activeTask.taskAddress)) {
451+
return (combatant, false, activeTask);
452+
}
453+
454+
address abstractedSender = _abstractedMsgSender();
455+
SessionKey memory key = _loadSessionKey(combatant.activeTask.taskAddress);
456+
457+
if (underlyingMsgSender == combatant.activeTask.taskAddress) {
458+
// CASE: We are evaluating this task inside of itself
459+
460+
if (key.expiration <= block.number && combatant.owner == key.owner) {
461+
if (combatant.owner == key.owner) {
462+
if (key.expiration > 0 && key.isTask) {
463+
_deactivateSessionKey(combatant.activeTask.taskAddress);
510464
}
511-
activeTask = _EMPTY_ADDRESS;
512-
} else if (key.expiration <= block.number) {
465+
combatant.activeTask.taskAddress = _EMPTY_ADDRESS;
466+
combatant.tracker.updateActiveTask = false;
513467
_clearActiveTask(combatant.id);
514-
if (combatant.owner == key.owner && key.expiration > 0 && key.isTask) {
515-
_deactivateSessionKey(activeTask);
468+
}
469+
} else if (abstractedSender != combatant.owner) {
470+
if (key.expiration > 0 && key.isTask) {
471+
_deactivateSessionKey(combatant.activeTask.taskAddress);
472+
}
473+
combatant.activeTask.taskAddress = _EMPTY_ADDRESS;
474+
combatant.tracker.updateActiveTask = false;
475+
_clearActiveTask(combatant.id);
476+
}
477+
return (combatant, true, combatant.activeTask.taskAddress);
478+
} else if (isTask && abstractedSender == combatant.owner) {
479+
// CASE: We are evaluating this task inside of another task with the same owner
480+
// is Task
481+
// taskPayor == combatant.owner
482+
// thisCaller != combatant.activeTask.taskAddress
483+
484+
if (key.owner == combatant.owner) {
485+
// CASE: SessionKey owner is combatant owner
486+
if (key.expiration <= block.number || activeBlock > combatant.activeTask.targetBlock) {
487+
if (key.expiration > 0 && key.isTask) {
488+
_deactivateSessionKey(combatant.activeTask.taskAddress);
516489
}
517-
activeTask = _EMPTY_ADDRESS;
518-
} else {
519-
hasActiveCombatTask = true;
490+
// Dont clear task - it could clear a new one _clearActiveTask(combatant.id);
491+
}
492+
return (combatant, true, activeTask);
493+
} else {
494+
// CASE: SessionKey owner doesn't match combatant owner, probably due to change
495+
if (key.expiration > 0 && key.isTask) {
496+
_deactivateSessionKey(combatant.activeTask.taskAddress);
497+
}
498+
return (combatant, false, _EMPTY_ADDRESS);
499+
}
500+
} else if (isTask) {
501+
// CASE: combatant owner doesn't match call owner
502+
// is Task
503+
// taskPayor != combatant.owner
504+
// thisCaller != combatant.activeTask.taskAddress
505+
506+
if (key.expiration <= block.number || activeBlock > combatant.activeTask.targetBlock) {
507+
if (key.expiration > 0 && key.isTask) {
508+
_deactivateSessionKey(combatant.activeTask.taskAddress);
520509
}
510+
return (combatant, false, activeTask);
521511
}
512+
return (combatant, true, activeTask);
513+
} else if (abstractedSender == combatant.owner && combatant.owner == key.owner) {
514+
// CASE: Not a task call - we know that the caller can be a payor
515+
if (key.expiration <= block.number || activeBlock > combatant.activeTask.targetBlock) {
516+
if (key.expiration > 0 && key.isTask) {
517+
_deactivateSessionKey(combatant.activeTask.taskAddress);
518+
}
519+
combatant.activeTask.taskAddress = _EMPTY_ADDRESS;
520+
combatant.tracker.updateActiveTask = false;
521+
_clearActiveTask(combatant.id);
522+
return (combatant, false, _EMPTY_ADDRESS);
523+
}
524+
return (combatant, true, activeTask);
525+
} else {
526+
// CASE: Not enough information to do anything consistent - just check expirations.
527+
if (key.expiration <= block.number || activeBlock > combatant.activeTask.targetBlock) {
528+
if (key.expiration > 0 && key.isTask) {
529+
_deactivateSessionKey(combatant.activeTask.taskAddress);
530+
}
531+
return (combatant, false, _EMPTY_ADDRESS);
532+
}
533+
return (combatant, hasActiveCombatTask, activeTask);
522534
}
523-
return (combatant, hasActiveCombatTask, activeTask);
524535
}
525536

526537
function areaCleanUp(uint8 depth, uint8 x, uint8 y) public {

0 commit comments

Comments
 (0)