Skip to content
This repository has been archived by the owner on Feb 21, 2019. It is now read-only.

Commit

Permalink
Introduce str file loader, welcome effects !
Browse files Browse the repository at this point in the history
  • Loading branch information
vthibault committed Apr 3, 2014
1 parent ae8f7bd commit 8cd630e
Show file tree
Hide file tree
Showing 11 changed files with 795 additions and 9 deletions.
32 changes: 27 additions & 5 deletions src/Core/Client.js
Expand Up @@ -9,8 +9,8 @@
* @author Vincent Thibault
*/

define( [ 'Utils/Executable', 'Network/PacketVerManager', './Thread', './MemoryManager', 'Utils/Texture'],
function( Executable, PACKETVER, Thread, Memory, Texture)
define( [ 'Utils/Executable', 'Network/PacketVerManager', './Thread', './MemoryManager', 'Utils/Texture', 'Utils/WebGL'],
function( Executable, PACKETVER, Thread, Memory, Texture, WebGL)
{
'use strict';

Expand Down Expand Up @@ -220,8 +220,8 @@ function( Executable, PACKETVER, Thread, Memo

function callback(data, error, input)
{
var i, count;
var gl, frames, texture, palette;
var i, count, j, size;
var gl, frames, texture, textures, layers, palette;
var precision, size;

if (data && !error) {
Expand All @@ -231,7 +231,29 @@ function( Executable, PACKETVER, Thread, Memo
Texture.load( data, function(){
Memory.set( input.filename, this.toDataURL(), error);
});
return;
return;

// Load str textures
case 'str':
gl = require('Renderer/Renderer').getContext();
layers = data.layers;

for (i = 0; i < data.layernum; ++i) {
layers[i].materials = new Array(layers[i].texcnt);

for (j = 0; j < layers[i].texcnt; ++j) {
(function(url, materials, textureId){
Client.loadFile( url, function(url){
WebGL.texture( gl, url, function(texture) {
materials[textureId] = texture;
});
});
})(layers[i].texname[j], layers[i].materials, j);
}
}

Memory.set(input.filename, data, error);
return;

case 'spr':
gl = require('Renderer/Renderer').getContext();
Expand Down
8 changes: 6 additions & 2 deletions src/Core/FileManager.js
Expand Up @@ -8,8 +8,8 @@
* @author Vincent Thibault
*/

define( ['Loaders/GameFile', 'Loaders/LuaByte', 'Loaders/World', 'Loaders/Ground', 'Loaders/Altitude', 'Loaders/Model', 'Loaders/Sprite', 'Loaders/Action', 'Core/FileSystem'],
function( GameFile, LuaByte, World, Ground, Altitude, Model, Sprite, Action, FileSystem )
define( ['Loaders/GameFile', 'Loaders/LuaByte', 'Loaders/World', 'Loaders/Ground', 'Loaders/Altitude', 'Loaders/Model', 'Loaders/Sprite', 'Loaders/Action', 'Loaders/Str', 'Core/FileSystem'],
function( GameFile, LuaByte, World, Ground, Altitude, Model, Sprite, Action, Str, FileSystem )
{
'use strict';

Expand Down Expand Up @@ -385,6 +385,10 @@ function( GameFile, LuaByte, World, Groun
result = new LuaByte(buffer).reverse();
break;

case 'str':
result = new Str(buffer);
break;

default:
result = buffer;
break;
Expand Down
51 changes: 51 additions & 0 deletions src/DB/EffectList.js
@@ -0,0 +1,51 @@
/**
* DB/EffectList.js
*
* List effects
* TODO: complete the list, add informations about sound.
*
* This file is part of ROBrowser, Ragnarok Online in the Web Browser (http://www.robrowser.com/).
*
* @author Vincent Thibault
*/

define(function()
{
"use strict";

return {
23: { str: 'stonecurse' },

29: { str: 'lightning' },
30: { str: 'thunderstorm' },

41: { str: 'angelus' },

66: { str: 'cure' },
67: { str: 'provoke' },
68: { str: 'mvp' },
69: { str: 'skidtrap' },

75: { str: 'gloria', wav:'priest_gloria' },
76: { str: 'magnificat' },
77: { str: 'resurrection' },

85: { str: 'lexaeterna' },
86: { str: 'aspersio' },
87: { str: 'lexdivina' },
88: { str: 'suffragium' },
89: { str: 'stormgust' },
90: { str: 'lord' },

102: { str: 'black_hammerfall' },
103: { str: 'weaponperfection' },
104: { str: 'maximizepower' },

111: { str: 'spring' },
112: { str: 'kyrie' },
113: { str: 'magnus' },

154: { str: 'bs_refinesuccess' },
155: { str: 'bs_refinefailed' },
};
});
36 changes: 36 additions & 0 deletions src/Engine/MapEngine/Skill.js
Expand Up @@ -17,16 +17,48 @@ define(function( require )
* Load dependencies
*/
var DB = require('DB/DBManager');
var EffectDB = require('DB/EffectList');
var SkillId = require('DB/SkillId');
var Session = require('Engine/SessionStorage');
var Network = require('Network/NetworkManager');
var PACKET = require('Network/PacketStructure');
var Effects = require('Renderer/Effects');
var StrEffect = require('Renderer/StrEffect');
var EntityManager = require('Renderer/EntityManager');
var Renderer = require('Renderer/Renderer');
var Sound = require('Audio/SoundManager');
var ShortCut = require('UI/Components/ShortCut/ShortCut');
var ChatBox = require('UI/Components/ChatBox/ChatBox');
var SkillWindow = require('UI/Components/SkillList/SkillList');
var SkillTargetSelection = require('UI/Components/SkillTargetSelection/SkillTargetSelection');


/**
* Spam an effect
*
* @param {object} pkt - PACKET.ZC.NOTIFY_EFFECT
*/
function onEffect( pkt )
{
if (pkt.effectID in EffectDB) {
var entity = EntityManager.get(pkt.AID);
var effect = EffectDB[pkt.effectID];

if (!entity) {
return;
}

if (effect.str) {
Effects.add(new StrEffect('data/texture/effect/' + effect.str + '.str', entity.position, Renderer.tick ), pkt.AID );
}

if (effect.wav) {
Sound.play('effect/' + effect.wav + '.wav');
}
}
}


/**
* Failed to cast a skill
*
Expand Down Expand Up @@ -240,5 +272,9 @@ define(function( require )
Network.hookPacket( PACKET.ZC.SHORTCUT_KEY_LIST, onShortCutList );
Network.hookPacket( PACKET.ZC.SHORTCUT_KEY_LIST_V2, onShortCutList );
Network.hookPacket( PACKET.ZC.ACK_TOUSESKILL, onSkillResult );
Network.hookPacket( PACKET.ZC.NOTIFY_EFFECT, onEffect );
Network.hookPacket( PACKET.ZC.NOTIFY_EFFECT2, onEffect );
Network.hookPacket( PACKET.ZC.NOTIFY_EFFECT3, onEffect );

};
});
119 changes: 119 additions & 0 deletions src/Loaders/Str.js
@@ -0,0 +1,119 @@
/**
* Loaders/Str.js
*
* Loaders for Gravity .str file (effects file)
* It's basically a .ezv file compiled to binary (except ezv file are version 0x95, str are 0x94).
*
* This file is part of ROBrowser, Ragnarok Online in the Web Browser (http://www.robrowser.com/).
*
* @author Vincent Thibault
*/

define( ['Utils/BinaryReader'], function( BinaryReader )
{
'use strict';


/**
* Str class loader
*
* @param {ArrayBuffer} data - optional
*/
function STR( data )
{
this.version = 0.0;

if (data) {
this.load(data);
}
}


/**
* Parse a STR file
*
* @param {ArrayBuffer} data
*/
STR.prototype.load = function load( data )
{
var fp, i;

fp = new BinaryReader(data);
this.header = fp.readString(4);

if (this.header !== 'STRM') {
throw new Error('STR::load() - Incorrect header "' + this.header + '", must be "STRM"');
}

this.version = fp.readULong();

if (this.version !== 0x94) {
throw new Error('STR - Invalid version "'+ this.version +'", not supported');
}

this.fps = fp.readULong();
this.maxKey = fp.readULong();
this.layernum = fp.readULong();
fp.seek(16, SEEK_CUR); // display, group, type, ... ?

this.layers = new Array(this.layernum);

for (i = 0; i < this.layernum; ++i) {
this.layers[i] = new STRLayer(fp);
}
};


/**
* Layer structure
*
* @param {BinaryReader} fp
*/
function STRLayer( fp )
{
var i;

this.texcnt = fp.readLong();
this.texname = new Array(this.texcnt);

for (i = 0; i < this.texcnt; ++i) {
this.texname[i] = 'data\\texture\\effect\\' + fp.readString(128);
}

this.anikeynum = fp.readLong();
this.animations = new Array(this.anikeynum);

for (i = 0; i < this.anikeynum; ++i) {
this.animations[i] = new STRAnimation(fp);
}
}


/**
* Frame structure
*
* @param {BinaryReader} fp
*/
function STRAnimation( fp )
{
this.frame = fp.readLong();
this.type = fp.readULong();
this.pos = new Float32Array([ fp.readFloat(), fp.readFloat() ]);
this.uv = new Float32Array([ fp.readFloat(), fp.readFloat(), fp.readFloat(), fp.readFloat(), fp.readFloat(), fp.readFloat(), fp.readFloat(), fp.readFloat() ]);
this.xy = new Float32Array([ fp.readFloat(), fp.readFloat(), fp.readFloat(), fp.readFloat(), fp.readFloat(), fp.readFloat(), fp.readFloat(), fp.readFloat() ]);
this.aniframe = fp.readFloat();
this.anitype = fp.readULong();
this.delay = fp.readFloat() * 1000;
this.angle = fp.readFloat() / (1024/360);
this.color = new Float32Array([ fp.readFloat() / 255.0, fp.readFloat() / 255.0, fp.readFloat() / 255.0, fp.readFloat() / 255.0 ]);
this.srcalpha = fp.readULong();
this.destalpha = fp.readULong();
this.mtpreset = fp.readULong();
}


/**
* Export
*/
return STR;
});
12 changes: 11 additions & 1 deletion src/Renderer/Effects.js
Expand Up @@ -55,6 +55,10 @@ define(function()
if (effect.constructor.init) {
effect.constructor.init(_gl);
}

if (!effect.constructor.renderBeforeEntities) {
effect.constructor.renderBeforeEntities = false;
}
}

if (effect.init) {
Expand Down Expand Up @@ -139,8 +143,9 @@ define(function()
* @param {object} fog structure
* @param {object} light structure
* @param {number} game tick
* @param {boolean} render before entities ?
*/
Effects.render = function render(gl, modelView, projection, fog, tick)
Effects.render = function render(gl, modelView, projection, fog, tick, renderBeforeEntities )
{
var keys = Object.keys(_list);
var i, count = keys.length;
Expand All @@ -157,6 +162,11 @@ define(function()

constructor = list[0].constructor;

// Will be render after/before.
if (constructor.renderBeforeEntities !== renderBeforeEntities) {
continue;
}

if (constructor.ready) {
constructor.beforeRender(gl, modelView, projection, fog, tick);

Expand Down
6 changes: 6 additions & 0 deletions src/Renderer/Effects/LockOnTarget.js
Expand Up @@ -209,6 +209,12 @@ function( WebGL, Texture, glMatrix, SkillId,
};


/**
* @var {boolean} should we render it before entities ?
*/
LockOnTarget.renderBeforeEntities = true;


/**
* Destroy objects
*
Expand Down
6 changes: 6 additions & 0 deletions src/Renderer/Effects/MagicTarget.js
Expand Up @@ -210,6 +210,12 @@ function( WebGL, glMatrix, SkillId, Client,
};


/**
* @var {boolean} should we render it before entities ?
*/
MagicTarget.renderBeforeEntities = true;


/**
* Destroy objects
*
Expand Down
4 changes: 3 additions & 1 deletion src/Renderer/MapRenderer.js
Expand Up @@ -350,8 +350,10 @@ define(function( require )
}
}

Effects.render( gl, modelView, projection, fog, tick );
Effects.render( gl, modelView, projection, fog, tick, true);
EntityManager.render( gl, modelView, projection, fog );
Effects.render( gl, modelView, projection, fog, tick, false);


Water.render( gl, modelView, projection, fog, light, tick );

Expand Down

0 comments on commit 8cd630e

Please sign in to comment.