Skip to content

Commit

Permalink
- Reldens - v4.0.0-beta.31
Browse files Browse the repository at this point in the history
- Merge pull request #232 from damian-pastorini/v4.0.0-beta.31
  • Loading branch information
damian-pastorini committed Jan 19, 2024
2 parents 58d5e2d + 46a33f2 commit f104fdc
Show file tree
Hide file tree
Showing 78 changed files with 1,402 additions and 831 deletions.
10 changes: 6 additions & 4 deletions README.md
Expand Up @@ -14,6 +14,10 @@ While the current stage of the platform is tailored for developers, ongoing impr

---

## [Check our website for the latest news!](https://www.reldens.com/ "Check our website for the latest news")

---

## [Features Overview](https://www.reldens.com/features)
[First to mention, if the feature you need is not available, you can request a feature here: https://www.reldens.com/features-request](https://www.reldens.com/features-request)

Expand Down Expand Up @@ -43,11 +47,9 @@ As for the latest version released the platform will provide you with the follow

---

## [Check our website for the latest news!](https://www.reldens.com/ "Check our website for the latest news")

---
## [Installation](https://www.reldens.com/documentation/installation "Installation")

## [Installation Guide](https://www.reldens.com/installation "Installation Guide")
Please follow the Installation Guide: https://www.reldens.com/documentation/installation.

---

Expand Down
4 changes: 3 additions & 1 deletion lib/actions/client/player-selector.js
Expand Up @@ -92,7 +92,9 @@ class PlayerSelector
let avatarKey = select.options[select.selectedIndex].dataset.key;
avatar.classList.add('class-path-select-avatar');
avatar.style.backgroundImage = `url('/assets/custom/sprites/${avatarKey}${GameConst.FILES.EXTENSIONS.PNG}')`;
avatar.style.width = playersConfig.size.width+'px';
let widthInPx = playersConfig.size.width+'px';
avatar.style.backgroundPositionX = '-'+widthInPx;
avatar.style.width = widthInPx;
avatar.style.height = playersConfig.size.height+'px';
select.addEventListener('change', () => {
let avatarKey = select.options[select.selectedIndex].dataset.key;
Expand Down
80 changes: 26 additions & 54 deletions lib/actions/client/preloader-handler.js
Expand Up @@ -2,48 +2,6 @@
*
* Reldens - PreloaderHandler.
*
* Main functionalities:
* The PreloaderHandler class is responsible for handling the preloading and creation of animations and assets used in
* the game. It loads HTML templates, spritesheets, and creates animations based on the configuration data provided by
* the game manager. It also handles the preparation and creation of animations with multiple directions and the
* creation of avatars animations.
*
* Methods:
* - constructor(props): initializes the class with the game manager and events manager objects, and sets the
* properties.
* - setProperties(props): sets the properties of the class, such as the game DOM, initial game data, and animations
* configuration.
* - loadContents(uiScene): loads HTML templates and preloads animations based on the configuration data.
* - preloadClassPaths(uiScene): preloads spritesheets for class paths based on the initial game data.
* - createAnimations(preloadScene): creates animations based on the configuration data.
* - createAvatarsAnimations(preloadScene): creates animations for avatars based on the initial game data.
* - loopAnimationsAnd(animations, command, uiScene): loops through the animations and executes the specified command
* (preload or create) for each animation.
* - preloadAnimation(data, uiScene): preloads animations based on the configuration data, including animations with
* multiple directions.
* - preloadAnimationsInDirections(data, uiScene): preloads animations in different directions based on the
* configuration data.
* - preloadSpriteInDirection(uiScene, data, direction): preloads a sprite in a specific direction based on the
* configuration data.
* - createAnimation(data, uiScene): creates animations based on the configuration data, including animations with
* multiple directions.
* - createWithMultipleDirections(uiScene, data, animDir): creates animations with multiple directions based on the
* configuration data.
* - createWithDirection(data, uiScene, direction = false): creates animations in a specific direction based on the
* configuration data.
* - prepareAnimationData(data, uiScene, direction = false): prepares the animation data based on the configuration
* data and direction.
* - getAnimationKey(data, direction = false): gets the animation key based on the configuration data and direction.
*
* Fields:
* - gameManager: the game manager object.
* - events: the events manager object.
* - gameDom: the game DOM object.
* - initialGameData: the initial game data object.
* - levelsAnimConfig: the levels animations configuration object.
* - skillsAnimConfig: the skills animations configuration object.
* - assetsCustomActionsSpritesPath: the path to the custom actions sprites assets.
*
*/

const { Logger, sc } = require('@reldens/utils');
Expand Down Expand Up @@ -79,7 +37,12 @@ class PreloaderHandler
'assetsCustomActionsSpritesPath',
'assets/custom/actions/sprites/'
);
this.gameManager.loadedAssets = {};
if(!this.gameManager.loadedAssets){
this.gameManager.loadedAssets = {};
}
if(!this.gameManager.createdAnimations){
this.gameManager.createdAnimations = {};
}
}

loadContents(uiScene)
Expand Down Expand Up @@ -127,34 +90,38 @@ class PreloaderHandler
{
let classesData = sc.get(this.initialGameData, 'classesData', false);
if(!classesData){
Logger.debug('Classes data not found. Fallback to player avatar.');
return false;
}
if(!this.gameManager.mappedAvatars){
this.gameManager.mappedAvatars = {};
}
Logger.debug({availableClassesData: classesData});
for(let i of Object.keys(classesData)){
let avatarKey = classesData[i].key;
if(!this.gameManager.loadedAssets[avatarKey]){
avatarKey = GameConst.IMAGE_PLAYER;
Logger.info('Avatar for class path "'+avatarKey+'" not found in assets. Fallback to player avatar.');
this.gameManager.mappedAvatars[avatarKey] = GameConst.IMAGE_PLAYER;
continue;
}
this.gameManager.mappedAvatars[avatarKey] = avatarKey;
return preloadScene.createPlayerAnimations(avatarKey);
preloadScene.createPlayerAnimations(avatarKey);
}
return this.gameManager.mappedAvatars;
}

loopAnimationsAnd(animations, command, uiScene)
{
if(!animations){
Logger.warning('Animations not found.', animations);
return false;
}
for(let i of Object.keys(animations)){
let data = animations[i];
if(!data.animationData.enabled){
Logger.debug('Animation "'+i+'" not enabled, skipping.', data);
continue;
}
// preloadAnimation or createAnimation
Logger.debug({[command+'Animation']: data});
this[command+'Animation'](data, uiScene);
}
}
Expand Down Expand Up @@ -242,19 +209,24 @@ class PreloaderHandler
}
}

createWithDirection(data, uiScene, direction = false)
createWithDirection(data, uiScene, direction = '')
{
let animationCreateData = this.prepareAnimationData(data, uiScene, direction);
let animation = uiScene.anims.create(animationCreateData);
if(this.gameManager.createdAnimations[animationCreateData.key]){
return this.gameManager.createdAnimations[animationCreateData.key];
}
let newAnimation = uiScene.anims.create(animationCreateData);
if(sc.hasOwn(data.animationData, 'destroyTime')){
animation.destroyTime = data.animationData.destroyTime;
newAnimation.destroyTime = data.animationData.destroyTime;
}
if(sc.hasOwn(data.animationData, 'depthByPlayer')){
animation.depthByPlayer = data.animationData.depthByPlayer;
newAnimation.depthByPlayer = data.animationData.depthByPlayer;
}
this.gameManager.createdAnimations[animationCreateData.key] = newAnimation;
return this.gameManager.createdAnimations[animationCreateData.key];
}

prepareAnimationData(data, uiScene, direction = false)
prepareAnimationData(data, uiScene, direction = '')
{
// @NOTE: here we use have two keys, the animation key and the animationData.img, this is because we could have
// a single sprite with multiple attacks, and use the start and end frame to run the required one.
Expand All @@ -275,9 +247,9 @@ class PreloaderHandler
return animationCreateData;
}

getAnimationKey(data, direction = false)
getAnimationKey(data, direction = '')
{
return (data.skillKey ? data.skillKey+'_' : '')+data.key+(direction ? '_'+direction : '');
return (data.skillKey ? data.skillKey+'_' : '')+data.key+(direction && '' !== direction ? '_'+direction : '');
}

}
Expand Down
9 changes: 5 additions & 4 deletions lib/actions/client/receiver-wrapper.js
Expand Up @@ -156,9 +156,7 @@ class ReceiverWrapper extends Receiver
targetSprite.moveSprites[hitAnimKey + '_' + targetSpriteId] = hitSprite;
}
let animData = allAnimations[hitAnimKey];
let depth = 'above' === sc.get(animData.animationData, 'depthByPlayer', '')
? targetSprite.depth + 100
: targetSprite.depth - 0.1;
let depth = targetSprite.depth+('above' === sc.get(animData.animationData, 'depthByPlayer', '') ? 100 : -0.1);
hitSprite.depthByPlayer = animData.animationData.depthByPlayer;
hitSprite.setDepth(depth);
return hitSprite;
Expand Down Expand Up @@ -270,7 +268,10 @@ class ReceiverWrapper extends Receiver
let sceneAnimation = currentScene.getAnimationByKey(animationKey);
if(!sceneAnimation){
if(-1 === animationKey.indexOf('default')){
Logger.error('Animation sprite not found', animationKey);
Logger.error(
'Animation sprite not found for "'+animationKey+'".',
this.gameManager.config.client.skills.animations
);
}
return false;
}
Expand Down
37 changes: 25 additions & 12 deletions lib/actions/server/battle.js
Expand Up @@ -32,17 +32,20 @@ class Battle
async runBattle(playerSchema, target)
{
if(GameConst.STATUS.ACTIVE !== playerSchema.inState){
Logger.info('Battle inactive player.', playerSchema.inState);
Logger.error('Battle inactive player with ID "'+playerSchema.player_id+'".', playerSchema.inState);
return false;
}
if(target.inState && GameConst.STATUS.ACTIVE !== target.inState){
Logger.info('Battle inactive target.', target.inState);
if(target.inState && GameConst.STATUS.ACTIVE.toString() !== target.inState.toString()){
Logger.error(
'Inactive target ID "'+(target.uid || target.player_id)
+'" in state "'+target.inState+'"/"'+GameConst.STATUS.ACTIVE+'".'
);
return false;
}
// @NOTE: each attack will have different properties to validate like range, delay, etc.
let currentAction = this.getCurrentAction(playerSchema);
if(!currentAction){
Logger.error(['Actions not defined for this player.', 'ID:', playerSchema.player_id]);
Logger.error('Actions not defined for this player with ID "'+playerSchema.player_id+'".');
return false;
}
currentAction.currentBattle = this;
Expand Down Expand Up @@ -92,6 +95,10 @@ class Battle

async clientDeathUpdate(targetSchema, room, targetClient, affectedProperty)
{
if(!targetSchema.player_id){
Logger.error('Target is not a player.', targetSchema.player_id);
return false;
}
targetSchema.inState = GameConst.STATUS.DEATH;
let actionData = new BattleEndAction(
targetSchema.state.x,
Expand All @@ -105,14 +112,20 @@ class Battle
await room.savePlayerState(targetSchema.sessionId);
targetClient.send('*', {act: GameConst.GAME_OVER});
await room.savePlayerStats(targetSchema, targetClient);
setTimeout(async () => {
room.roomWorld.addBody(body);
targetSchema.inState = GameConst.STATUS.ACTIVE;
// player is dead! reinitialize the stats using its base value:
targetSchema.stats[affectedProperty] = targetSchema.statsBase[affectedProperty];
await room.savePlayerStats(targetSchema, targetClient);
room.broadcast('*', {act: GameConst.REVIVED, t: targetSchema.sessionId});
}, (room.config.get('server/players/gameOver/timeOut') || 1));
targetSchema.setPrivate(
'playerDeathTimer',
setTimeout(
async () => {
room.roomWorld.addBody(body);
targetSchema.inState = GameConst.STATUS.ACTIVE;
// player is dead! reinitialize the stats using its base value:
targetSchema.stats[affectedProperty] = targetSchema.statsBase[affectedProperty];
await room.savePlayerStats(targetSchema, targetClient);
room.broadcast('*', {act: GameConst.REVIVED, t: targetSchema.sessionId});
},
(room.config.get('server/players/gameOver/timeOut') || 1)
)
);
return false;
}
}
Expand Down
10 changes: 7 additions & 3 deletions lib/actions/server/event-listeners.js
Expand Up @@ -5,14 +5,18 @@
*/

const { SkillsEvents } = require('@reldens/skills');
const { sc } = require('@reldens/utils');
const { Logger, sc } = require('@reldens/utils');

class EventListeners
{

static async attachCastMovementEvents(props)
{
let {classPath, events, actionsPlugin} = props;
if(!classPath || !events || !actionsPlugin){
Logger.critical('EventListeners: classPath, events or actionsPlugin undefined.', props);
return;
}
let ownerId = classPath.getOwnerEventKey();
classPath.listenEvent(
SkillsEvents.SKILL_BEFORE_CAST,
Expand All @@ -22,7 +26,7 @@ class EventListeners
}
skill.owner.physicalBody.isBlocked = true;
},
'skillBeforeCastPack',
classPath.getOwnerUniqueEventKey('skillBeforeCastPack'),
ownerId
);
classPath.listenEvent(
Expand All @@ -33,7 +37,7 @@ class EventListeners
}
skill.owner.physicalBody.isBlocked = false;
},
'skillAfterCastPack',
classPath.getOwnerUniqueEventKey('skillAfterCastPack'),
ownerId
);
await events.emit('reldens.actionsPrepareEventsListeners', actionsPlugin, classPath);
Expand Down
9 changes: 6 additions & 3 deletions lib/actions/server/player-enricher.js
Expand Up @@ -45,10 +45,13 @@ class PlayerEnricher
currentPlayer.getSkillExtraData = (params) => {
return SkillsExtraData.extractSkillExtraData(params);
};
currentPlayer.executePhysicalSkill = this.playerExecutePhysicalSkillCallback(currentPlayer, room);
currentPlayer.executePhysicalSkill = this.playerExecutePhysicalSkillCallback(
currentPlayer,
room.config.client.skills.animations
);
}

static playerExecutePhysicalSkillCallback(currentPlayer, room)
static playerExecutePhysicalSkillCallback(currentPlayer, skillsAnimationsData)
{
return async (target, executedSkill) => {
let messageData = Object.assign({skillKey: executedSkill.key}, executedSkill.owner.getPosition());
Expand All @@ -64,7 +67,7 @@ class PlayerEnricher
);
let from = {x: currentPlayer.state.x, y: currentPlayer.state.y};
executedSkill.initialPosition = from;
let animData = sc.get(room.config.client.skills.animations, executedSkill.key + '_bullet', false);
let animData = sc.get(skillsAnimationsData, executedSkill.key + '_bullet', false);
if(animData){
executedSkill.animDir = sc.get(animData.animationData, 'dir', false);
}
Expand Down

0 comments on commit f104fdc

Please sign in to comment.