ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/deliantra/html5client/main.js
Revision: 1.4
Committed: Sun Nov 4 21:08:36 2012 UTC (13 years, 10 months ago) by sf-demisephi
Content type: application/javascript
Branch: MAIN
Changes since 1.3: +206 -129 lines
Log Message:
added chat box messing around with containers (upditem,delitem,delinv ...)

File Contents

# User Rev Content
1 root 1.1 String.prototype.each = function (f,p){
2     for (var i=0;i<this.length;++i){
3     f.apply(this,[this[i],i,p]);
4     }
5     };
6    
7     Array.prototype.each = function (f,p){
8     for (var i=0;i<this.length;++i){
9     f.apply(this,[this[i],i,p]);
10     }
11     };
12    
13     Array.prototype.contains = function (e){
14     return this.indexOf(e) >= 0 && this.indexOf(e)<this.length;
15     }
16    
17     var canvas = null;
18     var canvasID = 'main';
19     var ctx = null;
20     var stage = null;
21     var Messages = [];
22     var output = null;
23     var commandline = null;
24    
25     var channels = {length: 0,list: []};
26    
27     var clickable = [];
28    
29     var extmap = true;
30     var Map = [];
31     var oldMapName = "";
32     var drawInventory = false;
33    
34     messageBox = window.alert;
35    
36     alert = function (s){
37     writeToScreen(s);
38     }
39    
40     var floorItems = [];
41     var myItems = [];
42     var mySpells = [];
43     var myStats = [];
44    
45    
46     var skillNames = [];
47    
48     var skipKeyTest = false;
49 sf-demisephi 1.4
50 root 1.1 var keys = {
51     shift: 0,
52     alt: 0,
53 sf-demisephi 1.3 ctrl: 0,
54     states : []
55 root 1.1 };
56    
57 sf-demisephi 1.4 var player = {
58     tag: 0,
59     weight: 0,
60     face: 0,
61     name: ""
62     }
63    
64    
65 root 1.1 var versionInfo = {
66     perlver: "5.014002",
67     clientver: "3.0Af0000000",
68     client: "deliantra",
69     gl_vendor: "NVIDIA Corporation",
70     gl_version: "4.2.0 NVIDIA 302.11",
71     modulever: "1.31",
72     osver: "linux",
73     protver: 1
74     };
75     var expTableFacenum = -1;
76    
77 sf-demisephi 1.3 var isRunning = false;
78     var isFiring = false;
79     mapsize = {width: 0,height:0};
80    
81 root 1.1 function appendToBody(e){
82     document.getElementsByTagName("body")[0].appendChild(e);
83     }
84    
85     function getPassword (){
86     return document.getElementById("password").value.trim();
87     }
88    
89     function getLogin (){
90     return document.getElementById("login").value.trim();
91     }
92    
93     function createCommandWindow (){
94     var div = createWindow("command",250,250,stage.stageWidth/2-250/2,stage.stageHeight-250/2);
95     var login = document.createElement("input");
96     login.type = "text";
97     login.placeholder = login.id = "command";
98     login.style.width = "100%";
99    
100 sf-demisephi 1.4 div.contents.appendChild(login);
101 root 1.1
102     var button = document.createElement("input");
103     button.type = "button";
104     button.value = "execute command";
105     button.style.width = "100%";
106 sf-demisephi 1.4 div.contents.appendChild(button);
107 root 1.1 button.addEventListener("click",function (e){
108 sf-demisephi 1.4 doSend("command " + login.value);
109     xCommmandWindow.show(false);
110 root 1.1 skipKeyTest = false;
111     })
112     var button = document.createElement("input");
113     button.type = "button";
114     button.value = "cancel";
115     button.style.width = "100%";
116 sf-demisephi 1.4 div.contents.appendChild(button);
117 root 1.1 button.addEventListener("click",function (e){
118 sf-demisephi 1.4 xCommmandWindow.show(false);
119 root 1.1 skipKeyTest = false;
120     })
121     return div;
122    
123     }
124    
125     var xMapWindow = null;
126     var xFloorWindow = null;
127     var xPlayerWindow = null;
128     var pattern = null;
129     var patternImage = null;
130     var isMainCalled = false;
131     var xInfoWindow = null;
132 sf-demisephi 1.3 var xBarsWindow = null;
133 sf-demisephi 1.4 var xCommmandWindow = null;
134     var xChatBoxWindow = null;
135 root 1.1
136     var wsUri = "ws://testserver.deliantra.net:13327/ws";
137     //var wsUri = "ws://slashflash.pl:13327/deliantra";
138     //var wsUri = "ws://localhost:13327/deliantra";
139    
140     function createWebSocket(){
141     var websocket = new WebSocket(wsUri);
142     websocket.onopen = function(evt) { onOpen(evt) };
143     websocket.onclose = function(evt) { onClose(evt) };
144     websocket.onmessage = function(evt) { onMessage(evt) };
145     websocket.onerror = function(evt) { onError(evt) };
146     return websocket;
147     }
148    
149    
150    
151     function createLoginWindow(){
152     var div = createWindow("login",260,180,stage.stageWidth/2-250/2,stage.stageHeight/2-250/2).contents;;
153     var login = document.createElement("input");
154     login.type = "text";
155     login.placeholder = login.id = "login";
156     login.style.width = "100%";
157     login.value = "deliantra login";
158     div.appendChild(login);
159     var password = document.createElement("input");
160     password.type = "password";
161     password.value = "";
162     password.style.width = "100%";
163     password.placeholder = password.id = "password";
164     div.appendChild(password);
165    
166     var button = document.createElement("input");
167     button.type = "button";
168     button.value = "logmein";
169     button.style.width = "100%";
170     div.appendChild(button);
171    
172    
173     button.addEventListener("click",function (e){
174     div.parent.style.display="none";
175     xMapWindow.contents.appendChild(canvas);
176     xMapWindow.show(true);
177     xFloorWindow.show(true);
178 sf-demisephi 1.3 xBarsWindow.show(true);
179 root 1.1 ctx.fillStyle = "#000";
180    
181 sf-demisephi 1.4
182 root 1.1 setInterval(draw,1000/5);
183    
184     websocket = new WebSocket(wsUri);
185     websocket.onopen = function(evt) { onOpen(evt) };
186     websocket.onclose = function(evt) { onClose(evt) };
187     websocket.onmessage = function(evt) { onMessage(evt) };
188     websocket.onerror = function(evt) { onError(evt) };
189     })
190     button = document.createElement("input");
191     button.type = "button";
192     button.value = "logmeinasnull";
193     button.style.width = "100%";
194     div.appendChild(button);
195     button.addEventListener("click",function (e){
196     login.value = password.value = "null";
197     div.parent.style.display="none";
198     xMapWindow.contents.appendChild(canvas);
199     xMapWindow.show(true);
200     xFloorWindow.show(true);
201 sf-demisephi 1.3 xBarsWindow.show(true);
202 root 1.1 ctx.fillStyle = "#000";
203     ctx.font = "10px Courier New,MonoSpace";
204     setInterval(draw,1000/5);
205    
206     websocket = new WebSocket(wsUri);
207     websocket.onopen = function(evt) { onOpen(evt) };
208     websocket.onclose = function(evt) { onClose(evt) };
209     websocket.onmessage = function(evt) { onMessage(evt) };
210     websocket.onerror = function(evt) { onError(evt) };
211     })
212     button = document.createElement("input");
213     button.type = "button";
214     button.value = "logmeinasNULL";
215     button.style.width = "100%";
216     div.appendChild(button);
217     button.addEventListener("click",function (e){
218     login.value = password.value = "NULL";
219     div.parent.style.display="none";
220     xMapWindow.contents.appendChild(canvas);
221     xMapWindow.show(true);
222     xFloorWindow.show(true);
223 sf-demisephi 1.3 xBarsWindow.show(true);
224 root 1.1 ctx.fillStyle = "#000";
225     ctx.font = "10px Courier New,MonoSpace";
226     setInterval(draw,1000/5);
227     websocket = new WebSocket(wsUri);
228     websocket.onopen = function(evt) { onOpen(evt) };
229     websocket.onclose = function(evt) { onClose(evt) };
230     websocket.onmessage = function(evt) { onMessage(evt) };
231     websocket.onerror = function(evt) { onError(evt) };
232     })
233     button = document.createElement("input");
234     button.type = "button";
235     button.value = "logmeinasVOID";
236     button.style.width = "100%";
237     div.appendChild(button);
238     button.addEventListener("click",function (e){
239     login.value = password.value = "VOID";
240     div.parent.style.display="none";
241     xMapWindow.contents.appendChild(canvas);
242     xMapWindow.show(true);
243     xFloorWindow.show(true);
244 sf-demisephi 1.3 xBarsWindow.show(true);
245 root 1.1 ctx.fillStyle = "#000";
246     ctx.font = "10px Courier New,MonoSpace";
247     setInterval(draw,1000/5);
248     websocket = new WebSocket(wsUri);
249     websocket.onopen = function(evt) { onOpen(evt) };
250     websocket.onclose = function(evt) { onClose(evt) };
251     websocket.onmessage = function(evt) { onMessage(evt) };
252     websocket.onerror = function(evt) { onError(evt) };
253     })
254     return div.parent;
255    
256    
257     }
258    
259 sf-demisephi 1.3 function draw(){
260     xBarsWindow.ctx.fillStyle = "#000";
261     xBarsWindow.ctx.fillRect(0,0,xBarsWindow.sw,xBarsWindow.sh);
262    
263    
264     if ( typeof (myStats[CS_STAT_MAXHP]) == typeof(1)){
265     xBarsWindow.ctx.save();
266    
267     xBarsWindow.ctx.fillStyle = "#F00";
268     xBarsWindow.ctx.globalAlpha = 0.5;
269     xBarsWindow.ctx.fillRect(10,10,20,xBarsWindow.sh);
270     xBarsWindow.ctx.fillRect(10,10+xBarsWindow.sh-(myStats[CS_STAT_HP]/myStats[CS_STAT_MAXHP])*xBarsWindow.sh,20,(myStats[CS_STAT_HP]/myStats[CS_STAT_MAXHP])*xBarsWindow.sh);
271     xBarsWindow.ctx.restore();
272     }
273    
274     if ( typeof (myStats[CS_STAT_MAXSP]) == typeof(1)){
275     xBarsWindow.ctx.save();
276    
277     xBarsWindow.ctx.fillStyle = "#00F";
278     xBarsWindow.ctx.globalAlpha = 0.5;
279     xBarsWindow.ctx.fillRect(50,10,20,xBarsWindow.sh);
280     xBarsWindow.ctx.fillRect(50,10+xBarsWindow.sh-(myStats[CS_STAT_SP]/myStats[CS_STAT_MAXSP])*xBarsWindow.sh,20,(myStats[CS_STAT_SP]/myStats[CS_STAT_MAXSP])*xBarsWindow.sh);
281     xBarsWindow.ctx.restore();
282     }
283     if ( typeof (myStats[CS_STAT_MAXGRACE]) == typeof(1)){
284     xBarsWindow.ctx.save();
285     xBarsWindow.ctx.fillStyle = "#0FF";
286     xBarsWindow.ctx.globalAlpha = 0.5;
287     xBarsWindow.ctx.fillRect(90,10,20,xBarsWindow.sh);
288     xBarsWindow.ctx.fillRect(90,10+xBarsWindow.sh-(myStats[CS_STAT_GRACE]/myStats[CS_STAT_MAXGRACE])*xBarsWindow.sh,20,(myStats[CS_STAT_GRACE]/myStats[CS_STAT_MAXGRACE])*xBarsWindow.sh);
289     xBarsWindow.ctx.restore();
290     }
291    
292     if ( typeof (myStats[CS_STAT_FOOD]) == typeof(1)){
293     xBarsWindow.ctx.save();
294     xBarsWindow.ctx.fillStyle = "#ff0";
295     xBarsWindow.ctx.globalAlpha = 0.5;
296     xBarsWindow.ctx.fillRect(130,10,20,xBarsWindow.sh);
297     xBarsWindow.ctx.fillRect(130,10+xBarsWindow.sh-(myStats[CS_STAT_FOOD]/999)*xBarsWindow.sh,20,(myStats[CS_STAT_FOOD]/999)*xBarsWindow.sh);
298     xBarsWindow.ctx.restore();
299     }
300     }
301    
302 root 1.1 function main (){
303 sf-demisephi 1.3
304     for (var i = 0;i<255;++i){
305     keys.states[i]=0;
306     };
307    
308 root 1.1 if (isMainCalled==true){
309     isMainCalled = true;
310     return;
311     }
312    
313     window.WebSocket = window.WebSocket || window.MozWebSocket;
314    
315     if (window.WebSocket){
316    
317    
318     canvas = document.createElement("canvas");
319     var sw = canvas.width = window.innerWidth-10;
320     var sh = canvas.height =window.innerHeight-10;
321     var dx = Math.floor(sw/64);
322     var dy = Math.floor((sh-120)/64);
323    
324     dx = dy = Math.min(dx,dy);
325     stage = {stageWidth:sw,stageHeight:sh};
326     var logWindow = createWindow("log",stage.stageWidth,120,0,0);
327     xMapWindow = createWindow("map",dx*64+30,dy*64+30,0,120);
328     xMapWindow.style.top = (sh-xMapWindow.height()-20)+"px";
329     xMapWindow.show(false);
330     canvas.width = xMapWindow.width()-10;
331     canvas.height = xMapWindow.height()-25;
332    
333    
334    
335    
336     xFloorWindow = createWindow("floor",Math.floor((sw-xMapWindow.width()-30)/2),350,xMapWindow.width()+30,stage.stageHeight-20-350);
337     xFloorWindow.show(false);
338    
339     xPlayerWindow = createWindow("player",sw - 30,sh-30,10,10);
340     //xPlayerWindow.show(false);
341    
342     xPlayerWindow.contents.innerHTML = "";
343     var buttons = ["Statistics","Skills","SpellBook","Inventory"];
344     var div = document.createElement("div");
345     div.className = "buttons_widnow_content";
346     xPlayerWindow.contents.appendChild(div);
347    
348     for (var i = 0;i<buttons.length;++i){
349     var button = document.createElement("input");
350     button.type="button";
351     button.value = buttons[i] + " (F"+(i+2)+")";
352     button.addEventListener("click",showPlayerTab);
353     div.appendChild(button);
354     }
355     div = document.createElement("div");
356     div.className = "player_widnow_content";
357     xPlayerWindow.contents.appendChild(div);
358    
359     div = document.createElement("div");
360     div.className = "floor_widnow_content";
361     xPlayerWindow.contents.appendChild(div);
362    
363     div = document.createElement("div");
364     div.className = "spellbook_widnow_content";
365     xPlayerWindow.contents.appendChild(div);
366    
367     div = document.createElement("div");
368     div.className = "skills_widnow_content";
369     xPlayerWindow.contents.appendChild(div);
370 sf-demisephi 1.3
371     div = document.createElement("div");
372     div.className = "statistics_widnow_content";
373     xPlayerWindow.contents.appendChild(div);
374    
375 root 1.1 hideAllPlayerTabs();
376    
377     xPlayerWindow.show(false);
378     ctx = canvas.getContext('2d');
379    
380     appendToBody(createLoginWindow());
381     window.addEventListener("click",onClick);
382     window.addEventListener("contextmenu",onClick);
383     window.addEventListener("mousemove",onMouseMove);
384     window.addEventListener("mouseup",onMouseUp);
385    
386     //document.getElementsByTagName("body")[0].addEventListener("contextmenu",onClick);
387     //document.addEventListener("contextmenu",onClick);
388    
389 sf-demisephi 1.3 output = $_("textarea");
390 root 1.1
391     output.style.opacity ="0.3";
392     output.style.filter ="filter:alpha(opacity=30);";
393    
394     output.style.width = "99%"
395     output.style.height = "70%";
396     logWindow.contents.appendChild(output);
397    
398 sf-demisephi 1.3 xBarsWindow = createWindow("bars",250,300,sw - 280,sh-320);
399     var barsCanvas = $_("canvas");
400     barsCanvas.width = xBarsWindow.sw = xBarsWindow.width() - 20;
401     barsCanvas.height =xBarsWindow.sh = xBarsWindow.height() - 20;
402     xBarsWindow.contents.appendChild(barsCanvas);
403     xBarsWindow.ctx = barsCanvas.getContext("2d");
404     xBarsWindow.ctx.fillStyle = "#000";
405     xBarsWindow.ctx.fillRect(0,0,xBarsWindow.sw,xBarsWindow.sh);
406     xBarsWindow.show(false);
407 root 1.1 xInfoWindow = createWindow("info",300,200,-400,-300);
408     xInfoWindow.show(false);
409 sf-demisephi 1.4 xCommmandWindow = createCommandWindow();
410     xCommmandWindow.show(false);
411     xChatBoxWindow = createWindow("chatbox",sw-xMapWindow.width()-20,300,sw-(sw-xMapWindow.width()-20),logWindow.height()+10);
412     xChatBoxWindow.buttonsContainer = $_("div");
413     xChatBoxWindow.contents.appendChild(xChatBoxWindow.buttonsContainer);
414     xChatBoxWindow.channelContainer = $_("div");
415     xChatBoxWindow.channelContainer.style.height = "100%";
416     xChatBoxWindow.contents.appendChild(xChatBoxWindow.channelContainer);
417    
418 root 1.1
419     }
420     };
421    
422     var currentWindow=null;
423     var currentWindowOffset = {x:0,y:0};
424     var currentWindowResize = false;
425    
426 sf-demisephi 1.3 function showPlayerTab (e,tn){
427    
428     xPlayerWindow.show(true);
429     var tabName = tn ? tn : (this.value).split(" ")[0].toLowerCase();
430 root 1.1
431     var div;
432    
433     switch (tabName){
434     case "inventory":
435     hideAllPlayerTabs();
436     var content = xPlayerWindow.getElementsByClassName("player_widnow_content")[0];
437     content.style.display = "block";
438     content = xPlayerWindow.getElementsByClassName("floor_widnow_content")[0];
439     content.style.display = "block";
440     updateItemsList();
441     break;
442     case "spellbook":
443    
444     hideAllPlayerTabs();
445     var content = xPlayerWindow.getElementsByClassName("spellbook_widnow_content")[0];
446     content.style.display = "block";
447     updateSpellList();
448     break;
449     case "skills":
450     hideAllPlayerTabs();
451     var content = xPlayerWindow.getElementsByClassName("skills_widnow_content")[0];
452     content.style.display = "block";
453     updateSkillList();
454 sf-demisephi 1.3 break;;
455     case "statistics":
456     hideAllPlayerTabs();
457     var content = xPlayerWindow.getElementsByClassName("statistics_widnow_content")[0];
458     content.style.display = "block";
459     updateStatsList();
460     break;;
461 root 1.1 default:
462 sf-demisephi 1.3
463 root 1.1 break;
464     }
465     }
466 sf-demisephi 1.3 var playerTabs = ["player_widnow_content","floor_widnow_content","spellbook_widnow_content","skills_widnow_content","statistics_widnow_content"];
467 root 1.1
468     function hideAllPlayerTabs (){
469     for (var i = 0;i<playerTabs.length;++i){
470     xPlayerWindow.getElementsByClassName(playerTabs[i])[0].style.display="none";
471     }
472     }
473    
474 sf-demisephi 1.3 function updateStatsList(){
475     var content = xPlayerWindow.getElementsByClassName("statistics_widnow_content")[0];
476     var div;
477     content.innerHTML = "";
478     var tableLeft;
479     var tableRight;
480     var tr;
481     var td;
482    
483     content.appendChild(div=$_("div"));
484     div.innerHTML = "Primary/Secondary statistics.";
485     content.appendChild($_("hr"));
486     content.appendChild(tableLeft = $_("table"));
487     tableLeft.style.width="45%";
488     tableLeft.style.float = "left";
489     content.appendChild(tableRight = $_("table"));
490     tableRight.style.width="45%";
491     tableRight.style.float = "right";
492     content.appendChild(div=$_("br"));
493     content.appendChild(div=$_("br"));
494     content.appendChild(div=$_("div"));
495     div.innerHTML = "Resistances.";
496     div.style.clear = "both";
497     content.appendChild($_("hr"));
498    
499     var j=0;
500    
501     var basicStats = [CS_STAT_STR,CS_STAT_INT,CS_STAT_WIS,CS_STAT_DEX,CS_STAT_CON,CS_STAT_CHA,CS_STAT_WC,CS_STAT_AC,CS_STAT_DAM,/*CS_STAT_ARMOUR,*/CS_STAT_SPEED,CS_STAT_WEAP_SP];
502     var basicStatsNames = ['CS_STAT_STR','CS_STAT_INT','CS_STAT_WIS','CS_STAT_DEX','CS_STAT_CON','CS_STAT_CHA','CS_STAT_WC','CS_STAT_AC','CS_STAT_DAM',/*'CS_STAT_ARMOUR',*/'CS_STAT_SPEED','CS_STAT_WEAP_SP'];
503    
504    
505     for (i=0;i<basicStats.length;++i){
506    
507     var table = i<6 ? tableLeft : tableRight;
508    
509     table.appendChild(tr = $_("tr"));
510     tr.index = i;
511    
512    
513     tr.appendChild(td=$_("td"));
514     td.innerHTML = basicStatsNames[i];
515    
516    
517     tr.appendChild(td=$_("td"));
518     td.innerHTML = myStats[basicStats[i]];
519    
520     };
521     var resNames = ['CS_STAT_RES_PHYS','CS_STAT_RES_MAG','CS_STAT_RES_FIRE','CS_STAT_RES_ELEC','CS_STAT_RES_COLD','CS_STAT_RES_CONF','CS_STAT_RES_ACID',
522     'CS_STAT_RES_DRAIN','CS_STAT_RES_GHOSTHIT','CS_STAT_RES_POISON','CS_STAT_RES_SLOW','CS_STAT_RES_PARA','CS_STAT_TURN_UNDEAD','CS_STAT_RES_FEAR',
523     'CS_STAT_RES_DEPLETE', 'CS_STAT_RES_DEATH', 'CS_STAT_RES_HOLYWORD','CS_STAT_RES_BLIND'];
524    
525     content.appendChild(tableLeft = $_("table"));
526     tableLeft.style.width="45%";
527     tableLeft.style.float = "left";
528     content.appendChild(tableRight = $_("table"));
529     tableRight.style.width="45%";
530     tableRight.style.float = "right";
531    
532     for (i=CS_STAT_RESIST_START;i<CS_STAT_RESIST_END;++i){
533     var table = i%2==0 ? tableLeft : tableRight;
534    
535     table.appendChild(tr = $_("tr"));
536     tr.index = i;
537    
538    
539     tr.appendChild(td=$_("td"));
540     td.innerHTML = resNames[i-CS_STAT_RESIST_START];
541    
542    
543     tr.appendChild(td=$_("td"));
544     td.innerHTML = myStats[i];
545    
546     }
547    
548    
549    
550    
551     }
552    
553     /*
554    
555    
556     CS_STAT_SKILLINFO = 140,
557     CS_NUM_SKILLS = 50,
558     SF_FIREON = 0x01,
559     SF_RUNON = 0x02,
560     NDI_BLACK = 0,
561     NDI_WHITE = 1,
562     NDI_NAVY = 2,
563     NDI_RED = 3,
564     NDI_ORANGE = 4,
565     NDI_BLUE = 5,
566     NDI_DK_ORANGE = 6,
567     NDI_GREEN = 7,
568     NDI_LT_GREEN = 8,
569     NDI_GREY = 9,
570     NDI_BROWN = 10,
571     NDI_GOLD = 11,
572     NDI_TAN = 12,
573     NDI_MAX_COLOR = 12,
574     NDI_COLOR_MASK = 0x1f,
575     NDI_REPLY = 0x20,
576     NDI_NOCRATE = 0x40,
577     NDI_CLEAR = 0x80,
578     a_none = 0,
579     a_readied = 1,
580     a_wielded = 2,
581     a_worn = 3,
582     a_active = 4,
583     a_applied = 5,
584     F_APPLIED = 0x000F,
585     F_LOCATION = 0x00F0,
586     F_UNPAID = 0x0200,
587     F_MAGIC = 0x0400,
588     F_CURSED = 0x0800,
589     F_DAMNED = 0x1000,
590     F_OPEN = 0x2000,
591     F_NOPICK = 0x4000,
592     F_LOCKED = 0x8000,
593     CF_FACE_NONE = 0,
594     CF_FACE_BITMAP = 1,
595     CF_FACE_XPM = 2,
596     CF_FACE_PNG = 3,
597     CF_FACE_CACHE = 0x10,
598     FACE_FLOOR = 0x80,
599     FACE_COLOR_MASK = 0xf,
600     UPD_LOCATION = 0x01,
601     UPD_FLAGS = 0x02,
602     UPD_WEIGHT = 0x04,
603     UPD_FACE = 0x08,
604     UPD_NAME = 0x10,
605     UPD_ANIM = 0x20,
606     UPD_ANIMSPEED = 0x40,
607     UPD_NROF = 0x80,
608     UPD_SP_MANA = 0x01,
609     UPD_SP_GRACE = 0x02,
610     UPD_SP_LEVEL = 0x04,
611     SOUND_NORMAL = 0,
612     SOUND_SPELL = 1,
613    
614     PICKUP_NOTHING = 0x00000000,
615    
616     PICKUP_DEBUG = 0x10000000,
617     PICKUP_INHIBIT = 0x20000000,
618     PICKUP_STOP = 0x40000000,
619     PICKUP_NEWMODE = 0x80000000,
620    
621     PICKUP_RATIO = 0x0000000F,
622    
623     PICKUP_FOOD = 0x00000010,
624     PICKUP_DRINK = 0x00000020,
625     PICKUP_VALUABLES = 0x00000040,
626     PICKUP_BOW = 0x00000080,
627    
628     PICKUP_ARROW = 0x00000100,
629     PICKUP_HELMET = 0x00000200,
630     PICKUP_SHIELD = 0x00000400,
631     PICKUP_ARMOUR = 0x00000800,
632    
633     PICKUP_BOOTS = 0x00001000,
634     PICKUP_GLOVES = 0x00002000,
635     PICKUP_CLOAK = 0x00004000,
636     PICKUP_KEY = 0x00008000,
637    
638     PICKUP_MISSILEWEAPON = 0x00010000,
639     PICKUP_ALLWEAPON = 0x00020000,
640     PICKUP_MAGICAL = 0x00040000,
641     PICKUP_POTION = 0x00080000,
642    
643     PICKUP_SPELLBOOK = 0x00100000,
644     PICKUP_SKILLSCROLL = 0x00200000,
645     PICKUP_READABLES = 0x00400000,
646     PICKUP_MAGIC_DEVICE = 0x00800000,
647    
648     PICKUP_NOT_CURSED = 0x01000000,
649    
650     PICKUP_JEWELS = 0x02000000,
651     PICKUP_FLESH = 0x04000000;
652     */
653 root 1.1
654     function updateItemsList(){
655     var content = xPlayerWindow.getElementsByClassName("player_widnow_content")[0];
656    
657    
658     content.innerHTML = "";
659     myItems.each(function (item,i,p){
660     if (isNaN(item.nr_of))
661     return;
662 sf-demisephi 1.3 content.appendChild(div = $_("div"));
663 root 1.1 var img = tilesInfo.getImgByFaceNum(item.face);
664     if (img){
665     div.innerHTML="<div><input type='hidden' value='"+item.itemId+"'/> <img src='"+img.src+"' alt='' style='width:32px;'/>"+(item.nr_of>1?item.namepl:item.name)+(item.nr_of>1?item.nr_of:"")+"</div>"
666     }else{
667     div.innerHTML="<div><input type='hidden' value='"+item.itemId+"'/>"+(item.nr_of>1?item.namepl:item.name)+"</div>"
668     }
669    
670     div.addEventListener("click",myInventoryItemClick);
671     div.addEventListener("mouseover",inventoryItemMouseOver);
672     div.addEventListener("mouseout",inventoryItemMouseOut);
673     div.addEventListener("mousemove",inventoryItemMouseMove);
674     },{})
675    
676     content = xPlayerWindow.getElementsByClassName("floor_widnow_content")[0];
677    
678    
679     content.innerHTML = "";
680 sf-demisephi 1.4 var container = secondaryContainer != 0 ? containers["container_" + secondaryContainer] : floorItems;
681     container.each(function (item,i,p){
682 root 1.1 if (isNaN(item.nr_of))
683     return;
684 sf-demisephi 1.3 content.appendChild(div = $_("div"));
685 root 1.1 var img = tilesInfo.getImgByFaceNum(item.face);
686     if (img){
687     div.innerHTML="<div><input type='hidden' value='"+item.itemId+"'/> <img src='"+img.src+"' alt='' style='width:32px;'/>"+(item.nr_of>1?item.namepl:item.name)+(item.nr_of>1?item.nr_of:"")+"</div>"
688     }else{
689     div.innerHTML="<div><input type='hidden' value='"+item.itemId+"'/>"+(item.nr_of>1?item.namepl:item.name)+"</div>"
690     }
691     div.addEventListener("mouseover",inventoryItemMouseOver);
692     div.addEventListener("mouseout",inventoryItemMouseOut);
693     div.addEventListener("mousemove",inventoryItemMouseMove);
694     div.addEventListener("click",floorInventoryItemClick);
695     },{})
696    
697     }
698    
699     function floorInventoryItemClick(e){
700     var itemId = parseInt(this.getElementsByTagName("input")[0].value);
701    
702     if (!keys.shift){
703     return;
704     }
705    
706     for (var i = 0;i<floorItems.length;++i){
707     if (parseInt(floorItems[i].itemId) == itemId){
708     doSend("command get "+ (floorItems[i].nr_of>1 ? floorItems[i].namepl:floorItems[i].name));
709     }else{
710    
711     }
712     }
713     }
714    
715     function myInventoryItemClick(e){
716     var itemId = parseInt(this.getElementsByTagName("input")[0].value);
717    
718     if (!keys.shift){
719     return;
720     }
721     for (var i = 0;i<myItems.length;++i){
722    
723    
724     if (parseInt(myItems[i].itemId) == itemId){
725     doSend("command drop "+ (myItems[i].nr_of>1 ? myItems[i].namepl:myItems[i].name));
726     }else{
727    
728     }
729     }
730    
731     }
732    
733     function inventoryItemMouseOver(e){
734     this.style.background = "solid";
735     this.style.backgroundColor="white";
736     var itemId = this.getElementsByTagName("input")[0].value;
737     doSend("ex " + itemId);
738    
739     xInfoWindow.show(true);
740     xInfoWindow.style.left = (e.clientX+5)+"px";
741     xInfoWindow.style.top = (e.clientY+5)+"px";
742     }
743    
744     function inventoryItemMouseMove(e){
745    
746     xInfoWindow.style.left = (e.clientX+5)+"px";
747     xInfoWindow.style.top = (e.clientY+5)+"px";
748    
749     }
750    
751     function inventoryItemMouseOut(e){
752     this.style.background = "transparent";
753     xInfoWindow.show(false);
754     }
755    
756     function createWindow(title,width,height,x,y){
757     var windowTemplate = document.getElementById("window_template_container").innerHTML;
758 sf-demisephi 1.3 var div = $_("div");
759 root 1.1 div.innerHTML = windowTemplate;
760    
761     var xwindow = div.getElementsByClassName("window")[0];
762     xwindow.style.left = x+"px";
763     xwindow.style.top = y+"px";
764     xwindow.style.width = width + "px";
765     xwindow.width = function (){
766     return parseInt(xwindow.style.width);
767     };
768    
769     xwindow.height = function (){
770     return parseInt(xwindow.style.height);
771     };
772     xwindow.show = function (b){
773     xwindow.style.display = b?"block":"none";
774     return true;
775     };
776     xwindow.visible = function (b){
777     return xwindow.style.display =="block";
778     };
779     xwindow.style.height = height + "px";
780     xwindow.getElementsByClassName("window_top_title")[0].innerHTML = title;
781     xwindow.getElementsByClassName("window_close")[0].onclick = function (){(xwindow.close());};
782     xwindow.onmousedown = function (e) { if (e.clientY-parseInt(xwindow.style.top)<25){
783     currentWindow = xwindow;
784     currentWindowOffset={x:e.clientX-parseInt(xwindow.style.left),y:e.clientY-parseInt(xwindow.style.top)}
785     }else if (e.clientY-parseInt(xwindow.style.top)>parseInt(xwindow.style.height)-5){
786     if (e.clientX-parseInt(xwindow.style.left)>parseInt(xwindow.style.width)-5){
787     currentWindowResize = true;
788     currentWindow = xwindow;
789     }
790     }
791     };
792     xwindow.contents = xwindow.getElementsByClassName("content")[0];
793     xwindow.contents.parent = xwindow;
794     xwindow.close = function (){document.getElementsByTagName("body")[0].removeChild(xwindow);};
795     appendToBody(xwindow);
796    
797    
798     return xwindow;
799     }
800     function onMouseUp (e){
801    
802     if (currentWindow!=null){
803     currentWindow = null;
804     currentWindowResize = false;
805     }
806     }
807    
808     function onMouseMove (e){
809     stage.mouseX = e.clientX;
810     stage.mouseY = e.clientY;
811     if (currentWindow!=null){
812     if (currentWindowResize == false){
813     currentWindow.style.left = (stage.mouseX-currentWindowOffset.x)+"px";
814     currentWindow.style.top = (stage.mouseY-currentWindowOffset.y)+"px";
815     }else{
816     currentWindow.style.width = (stage.mouseX-parseInt(currentWindow.style.left))+"px";
817     currentWindow.style.height = (stage.mouseY-parseInt(currentWindow.style.top))+"px";
818     }
819     }
820     }
821    
822     function ptInRect(pt,rect){
823     if (pt.x<rect.x) return false;
824     if (pt.y<rect.y) return false;
825     if (pt.x>rect.x+rect.width) return false;
826     if (pt.y>rect.y+rect.height) return false;
827     return true;
828     }
829    
830     function onClick (e){
831     x = e.clientX;
832     y = e.clientY;
833    
834     try{
835     e.preventDefault();
836     }catch (ex){
837    
838     }
839     return false;
840     }
841    
842     function channels_setActive(channel_info){
843     for (var i=0;i<channels.length;++i){
844     if (channels.list[i]==channel_info){
845     channels.list[i].isActive = true;
846     }else{
847     channels.list[i].isActive = false;
848     }
849     }
850     }
851    
852     function channels_addMessage(channelId,o){
853 sf-demisephi 1.4 var ta = channels_get_chat_box("channel_" + channelId);
854     ta.value = ta.value + JSON.stringify(o);;
855 root 1.1 channels[channelId].newMessages = true;
856     }
857    
858    
859     function channels_add(channel_info){
860 sf-demisephi 1.4 var button,textarea;
861     if (channels[channel_info['id']]){
862     return;
863     }
864 root 1.1 channel_info.messages = [];
865     channel_info.index = channels.list.length;
866     channels[channel_info['id']] = channel_info;
867     channels.list.push (channel_info);
868     channels.length+=1;
869     channels_setActive(channel_info);
870 sf-demisephi 1.4 xChatBoxWindow.buttonsContainer.appendChild(button=$_("input"));
871     button.value = channel_info['id'];
872     button.type = "button";
873     xChatBoxWindow.channelContainer.appendChild(textarea=$_("textarea"));
874     textarea.id = "channel_" + button.value;
875     textarea.style.width = "90%";
876     textarea.style.height = "85%";
877     channels_hide_other ("channel_" + button.value);
878     button.onclick = function (){
879     channels_hide_other ("channel_" + button.value);
880     };
881     }
882     function channels_get_chat_box (pid){
883     var list = xChatBoxWindow.channelContainer.getElementsByTagName("textarea");
884     for (var i=0;i<list.length;++i){
885     var e = list[i];
886     if (e.id == pid)
887     return e;
888     };
889     return null;
890 root 1.1 }
891 sf-demisephi 1.4 function channels_hide_other(pid){
892     var list = xChatBoxWindow.channelContainer.getElementsByTagName("textarea");
893     for (var i=0;i<list.length;++i){
894     var e = list[i];
895     if (e.id != pid)e.style.display = "none";else e.style.display = "block";
896     };
897 root 1.1 }
898    
899     function onOpen(evt)
900     {
901     writeToScreen("CONNECTED");
902     doSend('version {"clientver":"0.001","client":"deliantra html5 client","osver":"linux","protver":1}');
903     }
904    
905     function onClose(evt)
906     {
907     writeToScreen("DISCONNECTED");
908     }
909    
910     var exti = {
911     nextId : 100,
912     getNextId : function (){
913     return this.nextId++;
914     }
915     };
916    
917 sf-demisephi 1.4 function getItemById(itmid){
918     var itm = findItem(myItems,itmid);
919     if (itm){
920     return itm;
921     }
922     itm = findItem(floorItems,itmid);
923     if (itm){
924     return itm;
925     }
926     for (var s in containers){
927     if (typeof(containers[s]) == typeof({}) ){
928     itm = findItem(containers[s],itmid);
929     if (itm){
930     return itm;
931     }
932    
933     }
934     }
935     }
936    
937     function feed_upditem (data,dataAsArray){
938     var buff=new Buffer(dataAsArray);
939     buff.position = "upditem ".length;
940     var flags = buff.readUint8();
941     var tag = buff.readUint32();
942    
943     var itm = getItemById(tag);
944     if (!itm){
945     return;
946     }
947    
948     if (flags & UPD_LOCATION) {
949     removeItemEx(tag);
950    
951     var container = buff.readUint32();
952     if (container==player.tag){
953     myItems.push(itm);
954     }else if (container==0){
955     floorItems.push(itm);
956     }else{
957     if (!typof(containers["container_" + container])==typeof([])){
958     containers["container_" + container] = [];
959     }
960     containers["container_" + container].push (itm);
961     }
962     }
963     if (flags & UPD_FLAGS)
964     itm.flags = buff.readUint32();
965     if (flags & UPD_WEIGHT)
966     itm.weight = buff.readUint32();//$item->{weight} = unpack "l", pack "L", unpack "N", substr $data, 0, 4, "" ;
967     if (flags & UPD_FACE)
968     itm.face = buff.readUint32();
969    
970    
971     if((itm.flags&F_OPEN)){
972     secondaryContainer = tag;
973     updateItemsList();
974     }
975    
976     //TODO: finish it!
977     /*
978     if ($flags & UPD_NAME) {
979     my $len = unpack "C", substr $data, 0, 1, "";
980    
981     my $names = substr $data, 0, $len, "";
982     utf8::decode $names;
983     @$item{qw(name name_pl)} = split /\x00/, $names;
984     }
985    
986     $item->{anim} = unpack "n", substr $data, 0, 2, "" if $flags & UPD_ANIM;
987     $item->{animspeed} = TICK * unpack "C", substr $data, 0, 1, "" if $flags & UPD_ANIMSPEED;
988     $item->{nrof} = unpack "N", substr $data, 0, 4, "" if $flags & UPD_NROF;
989    
990     $item->{mtime} = time;
991    
992     if ($item->{tag} == $self->{player}{tag}) {
993     $self->player_update ($self->{player} = $item);
994     } else {
995     $self->item_update ($item);
996     }
997     */
998     }
999     function removeItemEx(itmid){
1000     removeItem(myItems,itmid);
1001     removeItem(floorItems,itmid);
1002     for (var s in containers){
1003     if (typeof(containers[s]) == typeof({}) ){
1004     removeItem(containers[s],itmid);
1005     }
1006     }
1007     }
1008 root 1.1 function feed_delitem (data,dataAsArray){
1009    
1010     var buff=new Buffer(dataAsArray);
1011     buff.position = 8;
1012    
1013     while (buff.position<dataAsArray.length){
1014     var itmid = buff.readUint32();
1015 sf-demisephi 1.4 removeItemEx(itmid);
1016     if (typeof(containers["container_" + itmid]) == typeof({}) ){
1017     containers["container_" + itmid] = [];
1018     }
1019    
1020 root 1.1 }
1021    
1022 sf-demisephi 1.4
1023     updateItemsList();
1024    
1025     }
1026     function findItem (items,itmid){
1027     for (var i=items.length-1;i>=0;--i){
1028     if (items[i].itemId == itmid){
1029     return items[i];
1030     }
1031     }
1032     return null;
1033 root 1.1 }
1034    
1035     function removeItem (items,itmid){
1036     for (var i=items.length-1;i>=0;--i){
1037     if (items[i].itemId == itmid){
1038     items.splice(i,1);
1039     }
1040     }
1041    
1042     updateItemsList();
1043     }
1044    
1045     function feed_ex (data,dataAsArray){
1046     var buff=new Buffer(dataAsArray);
1047     buff.position = 3;
1048     var len = buff.unpack_w();
1049     var str = buff.readString(len);
1050     xInfoWindow.contents.innerHTML = str.split("\n").join("<br/>")+"<small>shift+click - drop,move or pickup item</small>";
1051    
1052     }
1053    
1054     function feed_query (data,dataAsArray){
1055     switch (String.fromCharCode(dataAsArray[6])){
1056     case "0":
1057     //var login = prompt("What is your name? (login names are case-sensitive):");
1058     doSend("reply " + getLogin())
1059     return true;
1060     break;
1061    
1062     case "4":
1063     //var password = prompt("What is your password?");
1064     doSend("reply " + getPassword());
1065    
1066     return true
1067     break;
1068    
1069     }
1070     return false;
1071     }
1072    
1073    
1074 sf-demisephi 1.3 function onKeyDown (keyCode){
1075     switch(keyCode){
1076     case 38:
1077     if (keys.ctrl&&!isRunning){
1078     isRunning = true;
1079     doSend("command run 1");
1080     //doSend("command north")
1081     }
1082     else
1083     if (!isFiring&&keys.shift){
1084 sf-demisephi 1.4 doSend("command fire 1");
1085 sf-demisephi 1.3 isFiring = true;
1086     }else
1087     doSend("command north");
1088     break;
1089     case 40:
1090     if (keys.ctrl&&!isRunning){
1091     isRunning = true;
1092     doSend("command run 5" );
1093     //doSend("command souh")
1094     }
1095     else
1096     if (!isFiring&&keys.shift){
1097 sf-demisephi 1.4 doSend("command fire 5" );
1098 sf-demisephi 1.3 isFiring = true;
1099     }else
1100     doSend("command south");
1101     break;
1102     case 37:
1103     if (keys.ctrl&&!isRunning){
1104     isRunning = true;
1105     doSend("command run 7" );
1106     // doSend("command west")
1107     }
1108     else
1109     if (!isFiring&&keys.shift){
1110 sf-demisephi 1.4 doSend("command fire 7");
1111 sf-demisephi 1.3 isFiring = true;
1112     }else
1113     doSend("command west");
1114     break;
1115     case 39:
1116     if (keys.ctrl&&!isRunning){
1117     isRunning = true;
1118     doSend("command run 3" );
1119     //doSend("command west")
1120     }else
1121     if (!isFiring&&keys.shift){
1122 sf-demisephi 1.4 doSend("command fire 3");
1123 sf-demisephi 1.3 isFiring = true;
1124     }else
1125     doSend("command east");
1126     break;
1127     case 49:
1128     case 9:
1129     xPlayerWindow.show(!xPlayerWindow.visible() );
1130     break;
1131 sf-demisephi 1.4 case 67:
1132     skipKeyTest = true;
1133     xCommmandWindow.show(true);
1134    
1135     break;
1136 sf-demisephi 1.3
1137     case 32:
1138     doSend("command apply");
1139     break;
1140     case 188:
1141     doSend("command get");
1142     break;
1143     case 16:
1144     keys.shift = 1;
1145     break;
1146     case 18:
1147     keys.alt = 1;
1148     break;
1149     case 17:
1150     keys.ctrl = 1;
1151     break;
1152     case 113:
1153     showPlayerTab({},"statistics");
1154     break;
1155     case 114:
1156     showPlayerTab({},"skills");
1157     break;
1158    
1159     case 115:
1160     showPlayerTab({},"spellbook");
1161     break;
1162    
1163     case 116:
1164     showPlayerTab({},"inventory");
1165     break;
1166     default:
1167 sf-demisephi 1.4 //messageBox(keyCode);
1168 sf-demisephi 1.3 break;
1169     }
1170     }
1171    
1172     function onKeyUp(keyCode){
1173     switch(keyCode){
1174     case 38:
1175     if (isRunning&&!keys.ctrl){
1176     doSend("command run_stop");
1177     isRunning = false;
1178     }
1179     if (isFiring&&!keys.shift){
1180     doSend("command fire_stop");
1181     isFiring = false;
1182     }
1183     break;
1184     case 40:
1185     if (isFiring&&!keys.shift){
1186     doSend("command fire_stop");
1187     isFiring = false;
1188     }
1189     if (isRunning&&!keys.ctrl){
1190     doSend("command run_stop");
1191     isRunning = false;
1192     }
1193     break;
1194     case 37:
1195     if (isFiring&&!keys.shift){
1196     doSend("command fire_stop");
1197     isFiring = false;
1198     }
1199     if (isRunning&&!keys.ctrl){
1200     doSend("command run_stop");
1201     isRunning = false;
1202     }
1203     break;
1204     case 39:
1205     if (isFiring&&!keys.shift){
1206     doSend("command fire_stop");
1207     isFiring = false;
1208     }
1209     if (isRunning&&!keys.ctrl){
1210     doSend("command run_stop");
1211     isRunning = false;
1212     }
1213     break;
1214     case 49:
1215     break;
1216     case 16:
1217     keys.shift = 0;
1218 sf-demisephi 1.4 if (isFiring&&!keys.shift){
1219     doSend("command fire_stop");
1220     isFiring= false;
1221     }
1222 sf-demisephi 1.3 break;
1223     case 18:
1224     keys.alt = 0;
1225     break;
1226     case 17:
1227     keys.ctrl = 0;
1228     if (isRunning&&!keys.ctrl){
1229     doSend("command run_stop");
1230     isRunning = false;
1231     }
1232     break;
1233     default:
1234     //messageBox(e.keyCode);
1235     break;
1236     }
1237 root 1.1
1238 sf-demisephi 1.3 }
1239 root 1.1 function feed_version (data,dataAsArray){
1240     var smapsize = Math.floor(xMapWindow.width()/64);
1241     mapsize.width = mapsize.height = parseInt(smapsize);
1242     smapsize = smapsize +"x" + smapsize;
1243 sf-demisephi 1.2 map_clear();
1244 root 1.1 doSend('setup tileset 1 excmd 1 smoothing 1 mapinfocmd 1 facecache 1 newmapcmd 1 extmap 1 fxix 3 darkness 1 extcmd 2 msg 2 frag 0 map1acmd 1 spellmon 1 itemcmd 2 exp64 1 widget 1 lzf 0 mapsize ' + smapsize);
1245    
1246     window.addEventListener("keydown",function (e){
1247     if (skipKeyTest){
1248     return;
1249     }
1250    
1251 sf-demisephi 1.3 if (keys.states [e.keyCode]==0){
1252     onKeyDown(e.keyCode);
1253 root 1.1 }
1254 sf-demisephi 1.3
1255     keys.states [e.keyCode] = 1;
1256    
1257 root 1.1 try {
1258     e.preventDefault();
1259     }catch (e){
1260 sf-demisephi 1.3
1261 root 1.1 }
1262     return false;
1263     });
1264     window.addEventListener("keyup",function (e){
1265     if (skipKeyTest){
1266     return;
1267     }
1268 sf-demisephi 1.3 if (keys.states [e.keyCode]==1){
1269     onKeyUp(e.keyCode);
1270 root 1.1 }
1271 sf-demisephi 1.3 keys.states [e.keyCode] = 0;
1272 root 1.1 try {
1273     e.preventDefault();
1274     }catch (e){
1275    
1276     }
1277     //isRunning = false;
1278     return false;
1279     });
1280     channels_add({id:"log"});
1281     channels_add({id:"map"});
1282     return false;
1283     }
1284    
1285     function feed_setup (data,dataAsArray){
1286     doSend('exti ["http_faceurl", ' + exti.getNextId() +']');
1287     }
1288    
1289     //'',
1290     //'requestinfo spell_paths',
1291    
1292    
1293     function face2tile (){
1294    
1295     }
1296    
1297     function clear_cell (cell){
1298     cell.darkness = 256;
1299     cell.flags = 0;
1300     cell.player =0;
1301     cell.tiles = [];
1302    
1303    
1304     return cell;
1305     }
1306    
1307 sf-demisephi 1.2 function MapCell(){
1308     this.previousCell = null;
1309     this.nextCell = null;
1310     this.data = {};
1311     clear_cell(this.data);
1312     }
1313    
1314     function MapRow(){
1315     this.previousRow = null;
1316     this.nextRow = null;
1317     this.firstCell = null;
1318     this.lastCell = null;
1319     this.length = 0;
1320     while (this.length<mapsize.width){
1321     this.addCell(new MapCell());
1322     }
1323     }
1324     MapRow.prototype.addCell = function (cell){
1325     if (this.firstCell == null){
1326     this.firstCell = this.lastCell = cell;
1327    
1328     this.lastCell.nextCell = this.firstCell;
1329     this.lastCell.previousCell = this.firstCell;
1330    
1331     this.firstCell.nextCell = this.lastCell;
1332     this.firstCell.previousCell = this.lastCell;
1333    
1334     this.length = 1;
1335     return;
1336     }
1337     this.lastCell.nextCell = cell;
1338     cell.previousCell = this.lastCell;
1339     this.lastCell = cell;
1340     this.firstCell.previousCell = cell;
1341     cell.nextCell = this.firstCell;
1342     this.length+=1;
1343     }
1344    
1345     MapRow.prototype.shift = function (){
1346     var ret = this.firstCell;
1347     this.firstCell = ret.nextCell;
1348     this.lastCell.nextCell = this.firstCell;
1349     this.firstCell.previousCell = this.lastCell;
1350     return ret;
1351 root 1.1 }
1352    
1353 sf-demisephi 1.2 MapRow.prototype.pop = function (){
1354     var ret = this.lastCell;
1355     this.lastCell = ret.previousCell;
1356     this.lastCell.nextCell = this.firstCell;
1357     this.firstCell.previousCell = this.lastCell;
1358     return ret;
1359     }
1360 root 1.1
1361 sf-demisephi 1.2 MapRow.prototype.push = function (cell){
1362     this.addCell(cell);
1363     }
1364 root 1.1
1365 sf-demisephi 1.2 MapRow.prototype.unshift = function (cell){
1366     var tmp = this.firstCell;
1367     this.firstCell = cell;
1368     this.firstCell.nextCell = tmp;
1369     tmp.previousCell = this.firstCell;
1370     this.firstCell.previousCell = this.lastCell;
1371     this.lastCell.nextCell = this.firstCell;
1372 root 1.1 }
1373    
1374 sf-demisephi 1.2 function map_clear (){
1375     Map = {length:0,firstRow:null,lastRow : null,addRow:function (row){
1376     if (this.firstRow==null){
1377     this.firstRow = this.lastRow = row;
1378     this.length = 1;
1379     return;
1380 root 1.1 }
1381 sf-demisephi 1.2 this.lastRow.nextRow = row;
1382     row.previousRow = this.lastRow;
1383     this.lastRow = row;
1384     row.nextRow = this.firstRow;
1385     this.firstRow.previousRow = row;
1386     this.length++;
1387     }};
1388    
1389     while (Map.length<mapsize.height){
1390     Map.addRow(new MapRow());
1391 root 1.1 }
1392    
1393 sf-demisephi 1.2 if (stage&&stage.stageWidth)
1394     ctx.clearRect(0,0,stage.stageWidth,stage.stageHeight);
1395     }
1396 root 1.1
1397 sf-demisephi 1.2 function map_get_cell (x,y){
1398     var i = 0;
1399     var mapRow = Map.firstRow;
1400     while (i<y){
1401     mapRow = mapRow.nextRow;
1402     ++i;
1403     }
1404     i = 0;
1405     var mapCell = mapRow.firstCell;
1406     while (i<x){
1407     mapCell=mapCell.nextCell;
1408     ++i;
1409     }
1410     return mapCell.data;
1411 root 1.1 }
1412    
1413 sf-demisephi 1.3 function map_get_cell_ex (x,y){
1414     var i = 0;
1415     var mapRow = Map.firstRow;
1416     while (i<y){
1417     mapRow = mapRow.nextRow;
1418     ++i;
1419     }
1420     i = 0;
1421     var mapCell = mapRow.firstCell;
1422     while (i<x){
1423     mapCell=mapCell.nextCell;
1424     ++i;
1425     }
1426     return mapCell;
1427    
1428     }
1429    
1430 root 1.1 function scroll_map (dx,dy){
1431     var x,y;
1432     var tmpDx = dx;
1433     var tmpDy = dy;
1434 sf-demisephi 1.2 var i=0;
1435     while (i<tmpDy){
1436 root 1.1
1437 sf-demisephi 1.2 Map.firstRow = Map.firstRow.nextRow;
1438     Map.addRow(new MapRow());
1439     Map.length -=1;
1440     ++i;
1441     }
1442     i=0;
1443     while (tmpDy<i){
1444     var mapRow = new MapRow();
1445     mapRow.nextRow = Map.firstRow;
1446     Map.firstRow.previousRow = mapRow;
1447     mapRow.previousRow = Map.lastRow;
1448     Map.lastRow.nextRow = mapRow;
1449     Map.firstRow = mapRow;
1450     --i;
1451     }
1452     i = 0;
1453     while (i<tmpDx){
1454     var row = Map.firstRow;
1455     do {
1456     row.shift();
1457     row.push(new MapCell());
1458     row = row.nextRow;
1459     }while (row!=Map.firstRow);
1460     i++;
1461     }
1462     i = 0;
1463     while (tmpDx<i){
1464     var row = Map.firstRow;
1465     do {
1466     row.pop();
1467     row.unshift(new MapCell());
1468     row = row.nextRow;
1469     }while (row!=Map.firstRow);
1470     i--;
1471 root 1.1 }
1472     }
1473    
1474     function feed_map1a (stringData,data){
1475 sf-demisephi 1.2
1476 root 1.1 scroll_map(dx,dy);
1477     dx = dy = 0;
1478    
1479     var x,y;
1480    
1481     var index = 6;
1482 sf-demisephi 1.2
1483     while (index<data.length-2){
1484 root 1.1 var flags = (data[index++]<<8) + data[index++];
1485     x = ((flags >> 10) & 63);
1486     y = ((flags >> 4) & 63);
1487    
1488     cell = map_get_cell (x, y);
1489     if (!(flags&15)){
1490     clear_cell(cell);
1491     //ctx.clearRect(x<<6,(y<<6),64,64);
1492     continue;
1493     }
1494    
1495     if (cell.darkness==0){
1496     cell.darkness = 256;
1497     }
1498    
1499     if ((flags & 8)){
1500     do {
1501     var cmd = 0;
1502     var ext = 0;
1503    
1504     ext = data[index++];
1505     cmd = ext & 0x7f;
1506     if (cmd<4){
1507     cell.darkness = 255 - ext * 64 + 1;
1508     }else if (cmd == 5){
1509     cell.stat_width = 1;
1510     cell.stat_hp = data[index++];
1511     }else if (cmd == 6) {// monster width{
1512     cell.stat_width = data[index++] + 1;
1513     }else if (cmd == 0x47){
1514     if (data[index] == 1) cell.player = data [index + 1];
1515     else if (data[index] == 2) cell.player = data [index + 2] + (data [index + 1] << 8);
1516     else if (data[index] == 3) cell.player = data [index + 3] + (data [index + 2] << 8) + (data [index + 1] << 16);
1517     else if (data[index] == 4) cell.player = data [index + 4] + (data [index + 3] << 8) + (data [index + 2] << 16) + (data [index + 1] << 24);
1518    
1519 sf-demisephi 1.2 index += data[index] +1;
1520 root 1.1 }
1521     else if (cmd == 8) // cell flags
1522     cell.flags = data[index++];
1523     else if (ext & 0x40) // unknown, multibyte => skip
1524     index+= data[index]+1;
1525     else
1526     index++;
1527     }while (ext&0x80);
1528     }
1529    
1530    
1531    
1532     for (var z = 0; z <= 2; ++z)
1533     if ((flags & (4 >> z)))
1534     {
1535     var face = (data [index++] << 8) + data [index++];
1536 sf-demisephi 1.2 //need_facenum (face);
1537 root 1.1 cell.tiles [z] = face;
1538     }
1539 sf-demisephi 1.2 //Map[y][x]=cell;
1540 root 1.1
1541    
1542     }
1543     drawMap();
1544     return true;
1545    
1546     }
1547    
1548     function drawMap(){
1549    
1550 sf-demisephi 1.2
1551 root 1.1 ctx.clearRect(0,0,stage.stageWidth,stage.stageHeight);
1552     ctx.fillStyle = "#000";
1553     ctx.fillRect(0,0,canvas.width,canvas.height);
1554    
1555     for (var i = 0;i<mapsize.height;++i){
1556 sf-demisephi 1.3 var cell = map_get_cell_ex(0,i);
1557 root 1.1 for (var j=0;j<mapsize.width;++j){
1558     var x = j<<6;
1559     var y = i<<6;
1560 sf-demisephi 1.3 var cellx = cell.data;
1561 root 1.1 for (var z=0;z<=2;++z){
1562     if (!cellx.tiles[z])
1563     continue;
1564     var img = tilesInfo.getImgByFaceNum(cellx.tiles[z]);
1565     if (img){
1566     ctx.drawImage(img,x,y);
1567     }else{
1568    
1569     }
1570     }
1571 sf-demisephi 1.3 if ((typeof(cellx.stat_hp) == typeof(1))&&cellx.stat_hp>0){
1572     ctx.fillStyle = "#f00";
1573     ctx.fillRect(x,y,((255-cellx.stat_hp)/255)*64,8);
1574    
1575     //ctx.fillText(cellx.stat_hp,x,y);
1576     }
1577     cell = cell.nextCell;
1578    
1579 root 1.1 }
1580     }
1581     }
1582    
1583     function feed_ext (data,dataAsArray){
1584    
1585    
1586    
1587    
1588    
1589     if (data.indexOf ("channel_info")>0){
1590     var channel_info = JSON.parse(data.substr(4))[1];
1591     channels_add(channel_info);
1592     return true;
1593     }else{
1594    
1595     var o = JSON.parse(data.substr(4));
1596     var replyID = parseInt(o[0].split("-")[1]);
1597    
1598     if (replyID == 100){
1599     baseURL = o[1];
1600     baseURL = "http://testserver.deliantra.net:13327" + baseURL + "";
1601 sf-demisephi 1.3 doSend('exti ["resource",'+exti.getNextId()+',"exp_table"]');
1602    
1603 root 1.1
1604     }else if (replyID==101){
1605     expTableFacenum = parseInt(o[1]);
1606 sf-demisephi 1.3 doSend ('exti ["resource",'+exti.getNextId() + ',"exp_table", "skill_info", "spell_paths"]');
1607     }else if (replyID==102){
1608 root 1.1 doSend("addme");
1609     }
1610     else{
1611    
1612     }
1613    
1614    
1615     writeToScreen(data);
1616     }
1617     return false;
1618     }
1619     var Constants = {
1620     a_none : 0,
1621     a_readied : 1,
1622     a_wielded : 2,
1623     a_worn : 3,
1624     a_active : 4,
1625     a_applied : 5,
1626     F_APPLIED : 0x000F,
1627     F_LOCATION : 0x00F0,
1628     F_UNPAID : 0x0200,
1629     F_MAGIC : 0x0400,
1630     F_CURSED : 0x0800,
1631     F_DAMNED : 0x1000,
1632     F_OPEN : 0x2000,
1633     F_NOPICK : 0x4000,
1634     F_LOCKED : 0x8000
1635     };
1636     function Buffer (dataArray){
1637     this.buffer = dataArray;
1638     this.position = 0;
1639     this.length = dataArray.length;
1640     return this;
1641     }
1642    
1643     Buffer.prototype.unpack_w = function (){
1644     var num = 0;
1645     var byte = 0;
1646     do {
1647     num*=128;
1648     byte = parseInt(this.buffer[this.position++]);
1649     num+=byte&0x7f;
1650     }while (byte&0x80);
1651     return num;
1652     };
1653    
1654     Buffer.prototype.readUint32 = function (){
1655     var ret = 0;
1656     for (var i=0;i<4;++i){
1657     ret*=256;
1658     ret+=this.buffer[this.position++];
1659     }
1660     return ret;
1661     };
1662    
1663     Buffer.prototype.readUint8 = function (){
1664     var ret = 0;
1665     for (var i=0;i<1;++i){
1666     ret*=256;
1667     ret+=parseInt(this.buffer[this.position++]);
1668     }
1669     return ret;
1670     };
1671    
1672     Buffer.prototype.readUint16 = function (){
1673     var ret = 0;
1674     for (var i=0;i<2;++i){
1675     ret*=256;
1676     ret+=this.buffer[this.position++];
1677     }
1678     return ret;
1679     };
1680    
1681     Buffer.prototype.readString = function (len){
1682     var ret = "";
1683    
1684     if ( typeof (len) != "undefined"){
1685     for (var i=0;i<len;++i){
1686     ret+=String.fromCharCode(this.buffer[this.position++]);
1687     }
1688     }else{
1689    
1690     while (this.buffer[this.position]!=0){
1691     ret+=String.fromCharCode(this.buffer[this.position++]);
1692     }
1693     }
1694    
1695     return ret;
1696     };
1697    
1698    
1699    
1700     function unselectable (target){
1701     target.setAttribute('unselectable','on');
1702     if (typeof target.onselectstart != "undefined") //IE route
1703     target.onselectstart = function() { return false }
1704     else if (typeof target.style.MozUserSelect != "undefined") //Firefox route
1705     target.style.MozUserSelect = "none"
1706     else //All other route (ie: Opera)
1707     target.onmousedown = function() { return false }
1708     }
1709    
1710     function Item (){
1711     this.itemId = 0;
1712     this.flags = 0;
1713     this.weight = 0;
1714     this.face = 0;
1715     this.name = "";
1716     this.namepl = "";
1717     this.animation_id=0;
1718     this.anim_speed=0;
1719     this.nr_of=0;
1720     this.clientType=0;
1721     }
1722    
1723    
1724     function feed_replyinfo (data){
1725 sf-demisephi 1.3 return false;
1726 root 1.1 }
1727    
1728 sf-demisephi 1.4 var containers = {};
1729     var secondaryContainer = 0;
1730    
1731 root 1.1 function feed_item2 (data,dataAsArray){
1732     var buff = new Buffer(dataAsArray);
1733     buff.position = 6;
1734     var container = buff.readUint32();
1735    
1736     while (buff.position<buff.length){
1737     var item = new Item();
1738    
1739     item.itemId = buff.readUint32();
1740    
1741     item.flags = buff.readUint32();
1742     item.weight = buff.readUint32();
1743     item.face = buff.readUint32();
1744     var len = (buff.readUint8());
1745    
1746     var names = (buff.readString(len)).split(String.fromCharCode(0));
1747     item.name = names[0];
1748     item.namepl = "";
1749    
1750     if (names.length>1)
1751     item.namepl = names[1];
1752    
1753     item.animation_id = buff.readUint16();
1754     item.anim_speed = buff.readUint8();
1755     item.nr_of = buff.readUint32();
1756     item.clientType = buff.readUint16();
1757 sf-demisephi 1.4 item.container = container;
1758    
1759     if (container==player.tag){
1760 root 1.1 myItems.push (item);
1761 sf-demisephi 1.4 }else if (container==0){
1762 root 1.1 floorItems.push(item);
1763 sf-demisephi 1.4 }else {
1764     if ( typeof(containers['container_' + container]) != typeof([])){
1765     containers['container_' + container] = [];
1766     }
1767     containers['container_' + container].push(item);
1768 root 1.1 }
1769     }
1770     if (container==0){
1771     xFloorWindow.contents.innerHTML="";
1772     for (var i=0;i<floorItems.length;++i){
1773     var item = floorItems[i];
1774     if (item.itemId==null||isNaN(item.itemId))
1775     continue;
1776     var img = tilesInfo.getImgByFaceNum(item.face);
1777 sf-demisephi 1.3 var div = $_("div");
1778 root 1.1 xFloorWindow.contents.appendChild(div);
1779     if (img){
1780     div.innerHTML+="<div><input type='hidden' value='"+item.itemId+"'/><img src='"+img.src+"' alt='' style='width:32px;'/>"+(item.nr_of>1?item.namepl:item.name)+(item.nr_of>1?item.nr_of:"")+"</div>"
1781     }else{
1782     div.innerHTML+="<div><input type='hidden' value='"+item.itemId+"'/>"+(item.nr_of>1?item.namepl:item.name)+"</div>"
1783     }
1784    
1785     div.addEventListener("click",floorInventoryItemClick);
1786     div.addEventListener("mouseover",inventoryItemMouseOver);
1787     div.addEventListener("mouseout",inventoryItemMouseOut);
1788     div.addEventListener("mousemove",inventoryItemMouseMove);
1789    
1790     }
1791    
1792    
1793     }
1794     updateItemsList();
1795     return false;
1796     }
1797    
1798     function Spell (){
1799    
1800     }
1801    
1802     function updateSpellList (){
1803     var content = xPlayerWindow.getElementsByClassName("spellbook_widnow_content")[0];
1804     content.style.display = "block";
1805    
1806     content.innerHTML = "";
1807     var table;
1808     var tr;
1809     var td;
1810    
1811 sf-demisephi 1.3 content.appendChild(table = $_("table"));
1812 root 1.1 table.style.width="100%";
1813     if (mySpells.length<=0){
1814     return;
1815     }
1816 sf-demisephi 1.3 table.appendChild(tr = $_("tr"));
1817 root 1.1 item = mySpells[0];
1818     for (s in item){
1819    
1820     if ((typeof(item[s])==typeof(1))||(typeof(item[s])==typeof(""))){
1821     if (s=="tag"){
1822    
1823     }else if (s=="message"){
1824    
1825     }else if (s=="face"){
1826 sf-demisephi 1.3 tr.appendChild(td=$_("td"));
1827 root 1.1 td.innerHTML = s;
1828     }else{
1829 sf-demisephi 1.3 tr.appendChild(td=$_("td"));
1830 root 1.1 td.innerHTML = s;
1831     }
1832     }
1833    
1834     }
1835    
1836    
1837     mySpells.each(function (item,i,p){
1838    
1839 sf-demisephi 1.3 table.appendChild(tr = $_("tr"));
1840 root 1.1 tr.index = i;
1841     var img = tilesInfo.getImgByFaceNum(item.face);
1842    
1843     var s;
1844     for (s in item){
1845     if (isNaN(item['face'])){
1846     continue;
1847     }
1848    
1849     if ((typeof(item[s])==typeof(1))||(typeof(item[s])==typeof(""))){
1850     if (s=="tag"){
1851     tr.tag = item[s];
1852     }else if (s=="message"){
1853     tr.message = item[s];
1854     }else if (s=="face"){
1855 sf-demisephi 1.3 tr.appendChild(td=$_("td"));
1856 root 1.1 td.innerHTML = "<img src='"+img.src+"' alt='' style='width:32px;'/>";
1857     }else{
1858 sf-demisephi 1.3 tr.appendChild(td=$_("td"));
1859 root 1.1 td.innerHTML = item[s];
1860     }
1861     }
1862    
1863     }
1864     tr.addEventListener("click",mySpellItemClick);
1865     tr.addEventListener("mouseover",SpellItemMouseOver);
1866     tr.addEventListener("mouseout",SpellItemMouseOut);
1867     tr.addEventListener("mousemove",SpellItemMouseMove);
1868    
1869     /*if (img){
1870     div.innerHTML="<div><input type='hidden' value='"+item.itemId+"'/> <img src='"+img.src+"' alt='' style='width:32px;'/>"+(item.nr_of>1?item.namepl:item.name)+(item.nr_of>1?item.nr_of:"")+"</div>"
1871     }else{
1872     div.innerHTML="<div><input type='hidden' value='"+item.itemId+"'/>"+(item.nr_of>1?item.namepl:item.name)+"</div>"
1873     }*/
1874    
1875    
1876     },{})
1877    
1878    
1879     }
1880     function updateSkillList (){
1881     var content = xPlayerWindow.getElementsByClassName("skills_widnow_content")[0];
1882    
1883    
1884     content.innerHTML = "";
1885     var tableLeft;
1886     var tableRight;
1887     var tr;
1888     var td;
1889    
1890 sf-demisephi 1.3 content.appendChild(tableLeft = $_("table"));
1891 root 1.1 tableLeft.style.width="45%";
1892     tableLeft.style.float = "left";
1893 sf-demisephi 1.3 content.appendChild(tableRight = $_("table"));
1894 root 1.1 tableRight.style.width="45%";
1895     tableRight.style.float = "right";
1896    
1897     var j=0;
1898    
1899     for (i=CS_STAT_SKILLINFO;i<CS_STAT_SKILLINFO+CS_NUM_SKILLS;++i){
1900    
1901     if (!myStats[i]){
1902     continue;
1903     }
1904     var table = j%2==0 ? tableLeft : tableRight;
1905    
1906 sf-demisephi 1.3 table.appendChild(tr = $_("tr"));
1907 root 1.1 tr.index = i;
1908    
1909    
1910 sf-demisephi 1.3 tr.appendChild(td=$_("td"));
1911     td.innerHTML = skillNames[i-CS_STAT_SKILLINFO][0];
1912 root 1.1
1913     for (var k =0 ;k<myStats[i].length;++k){
1914    
1915 sf-demisephi 1.3 tr.appendChild(td=$_("td"));
1916 root 1.1 td.innerHTML = myStats[i][k];
1917    
1918     }
1919 sf-demisephi 1.3 tr.appendChild(td=$_("td"));
1920     td.innerHTML = Math.floor(myStats[i][1]/expTable[parseInt(myStats[i][0])]*100) + "%";
1921 root 1.1 /*tr.addEventListener("click",mySpellItemClick);
1922     tr.addEventListener("mouseover",SpellItemMouseOver);
1923     tr.addEventListener("mouseout",SpellItemMouseOut);
1924     tr.addEventListener("mousemove",SpellItemMouseMove);
1925     */
1926     ++j;
1927     };
1928    
1929    
1930     }
1931    
1932     function mySpellItemClick(e){
1933     if (keys.ctrl){
1934     doSend("command invoke " + mySpells[this.index].name);
1935     }else if (keys.shift){
1936     doSend("command cast " + mySpells[this.index].name);
1937     }
1938     }
1939    
1940    
1941     function SpellItemMouseOver(e){
1942     this.style.background = "solid";
1943     this.style.backgroundColor="white";
1944    
1945     xInfoWindow.contents.innerHTML = this.message + "<small><br/>shift-click to cast<br/>ctrl-click to invoke</small>";
1946     xInfoWindow.show(true);
1947     xInfoWindow.style.left = (e.clientX+5)+"px";
1948     xInfoWindow.style.top = (e.clientY+5)+"px";
1949     }
1950    
1951     function SpellItemMouseMove(e){
1952    
1953     xInfoWindow.style.left = (e.clientX+5)+"px";
1954     xInfoWindow.style.top = (e.clientY+5)+"px";
1955    
1956     }
1957    
1958     function SpellItemMouseOut(e){
1959     this.style.background = "transparent";
1960     xInfoWindow.show(false);
1961     }
1962    
1963    
1964     function feed_addspell (data,dataAsArray){
1965    
1966     var buff = new Buffer(dataAsArray);
1967     buff.position = data.indexOf(" ")+1;
1968     while (buff.position<buff.length){
1969     spell=new Spell();
1970    
1971     spell.tag = buff.readUint32();
1972    
1973     spell.minLevel = buff.readUint16();
1974    
1975     spell.castingTime = buff.readUint16();
1976    
1977     spell.mana = buff.readUint16();
1978    
1979     spell.grace = buff.readUint16();
1980    
1981     spell.level = buff.readUint16();
1982    
1983     spell.skill = buff.readUint8();
1984    
1985     spell.path = buff.readUint32();
1986    
1987     spell.face = buff.readUint32();
1988     var len = buff.readUint8();
1989     spell.name = buff.readString(len);
1990     len = buff.readUint16();
1991     spell.message = buff.readString(len);
1992     mySpells.push(spell);
1993     }
1994    
1995    
1996     }
1997    
1998     function feed_delinv (data,dataAsArray){
1999     var container = parseInt(data.split(" ")[1]);
2000 sf-demisephi 1.4 if (container==player.tag){
2001 root 1.1 myItems = [];
2002 sf-demisephi 1.4 }else if (container!=0){
2003     containers["container_" +container]=[];
2004 root 1.1 }else{
2005     floorItems = [];
2006     }
2007 sf-demisephi 1.4 updateItemsList();
2008 root 1.1 return false;
2009     }
2010    
2011     var expTable = [0,1000,3000,7000,15000,31000,63000,98500,145000,210000,290000,400000,530000,695000,895000,1100000,1400000,1750000,2150000,2650000,3200000,3850000,4650000,5500000,6500000,7650000,8800000,10000000,11500000,13500000,15500000,18000000,20500000,23500000,26500000,30000000,34000000,38500000,43000000,48500000,54000000,60500000,67500000,75000000,83000000,91500000,100000000,110000000,120000000,130000000,145000000,160000000,175000000,190000000,210000000,230000000,250000000,275000000,300000000,325000000,350000000,380000000,410000000,445000000,480000000,520000000,560000000,605000000,655000000,705000000,755000000,810000000,870000000,930000000,990000000,1050000000,1100000000,1200000000,1250000000,1350000000,1450000000,1550000000,1650000000,1800000000,1900000000,2000000000,2150000000,2300000000,2450000000,2600000000,2750000000,2900000000,3100000000,3300000000,3500000000,3750000000,4050000000,4350000000,4750000000,5250000000,5850000000,6650000000,7650000000,9000000000,10500000000,13500000000,17000000000,23000000000,32000000000,47000000000,73000000000,120000000000,215000000000,430000000000,935000000000];
2012 sf-demisephi 1.3 var spellPaths = [];
2013 root 1.1
2014     function feed_fx (data,dataAsArray){
2015    
2016     var buff = new Buffer(dataAsArray);
2017     buff.position = 3;
2018     var ignore = true;
2019     while (buff.position<buff.length){
2020     var id = buff.unpack_w();
2021     var len = buff.readUint8();
2022     var nameX = "";
2023     for (var i = 0;i<len;++i){
2024     var c = parseInt(buff.readUint8());
2025     var out="";
2026     out+="0123456789abcdef"[c&0xf];
2027     out= "0123456789abcdef"[c>>4]+out;
2028     nameX+=out;
2029     }
2030 sf-demisephi 1.3 var img = $_("img");
2031 root 1.1
2032     var e;
2033     if (tilesInfo.getImgByFaceNum(id)){
2034    
2035     }else{
2036     if (nameX.length>3){
2037 sf-demisephi 1.3 if (nameX == "5d7a9b7f65deb9e99ce0dd74560eb0"){
2038 root 1.1 var req = new XMLHttpRequest();
2039     req.open('GET', baseURL+""+nameX, false);
2040     req.send(null);
2041     if(req.status == 200)
2042 sf-demisephi 1.3 skillNames = JSON.parse(req.responseText);
2043     }else if (nameX =="6c65c81502952fd958a6f794a0d34c"){
2044     var req = new XMLHttpRequest();
2045     req.open('GET', baseURL+""+nameX, false);
2046     req.send(null);
2047     if(req.status == 200)
2048     spellPaths = JSON.parse(req.responseText);
2049     }else if (nameX=="f66e1bc0a5662e59be0253a84ee06c"){
2050     var req = new XMLHttpRequest();
2051     req.open('GET', baseURL+""+nameX, false);
2052     req.send(null);
2053     if(req.status == 200)
2054     expTable = JSON.parse(req.responseText);
2055 root 1.1 }else{
2056     tilesInfo.listLoading.push (e={name:nameX,id:id,img:img,src:baseURL+""+nameX});
2057     e.img.parent = e;
2058     e.img.onload = function (){tilesInfo.markAsLoaded(this.parent);}
2059     if (!tilesInfo.isLoading){
2060    
2061     tilesInfo.isLoading = true;
2062     e.img.src = e.src;
2063     //alert("loading: " + e.src);
2064     }
2065     }
2066     }else{
2067     //alert ("face num " + id + " has name len :" + len + " !!!!");
2068     //prompt("",dataAsArray);
2069     }
2070     }
2071     }
2072    
2073     return false;
2074     }
2075    
2076    
2077     function feed_newmap (data,dataAsArray){
2078     //messageBox("newmap");
2079     map_clear();
2080 sf-demisephi 1.2
2081 root 1.1 }
2082    
2083     function feed_mapinfo (data,dataAsArray){
2084     var parts = data.split(/ /);
2085     //map_clear();
2086     return false;
2087     }
2088    
2089    
2090     function feed_msg (data,dataAsArray){
2091     var o = null;
2092     if (data.indexOf("[")>0){
2093     o = JSON.parse(data.substr(4));
2094    
2095     channels_addMessage(o[1],o)
2096     return true;
2097     }
2098     return false;
2099     }
2100    
2101    
2102     function feed_anim (data,dataAsArray){
2103     return false;
2104     }
2105    
2106     /*
2107     CONSTANTS
2108     */
2109    
2110     var TICK = 0.120,
2111     CS_QUERY_YESNO = 0x1,
2112     CS_QUERY_SINGLECHAR = 0x2,
2113     CS_QUERY_HIDEINPUT = 0x4,
2114     CS_SAY_NORMAL = 0x1,
2115     CS_SAY_SHOUT = 0x2,
2116     CS_SAY_GSAY = 0x4,
2117     FLOAT_MULTI = 100000,
2118     FLOAT_MULTF = 100000.0,
2119     CS_STAT_HP = 1,
2120     CS_STAT_MAXHP = 2,
2121     CS_STAT_SP = 3,
2122     CS_STAT_MAXSP = 4,
2123     CS_STAT_STR = 5,
2124     CS_STAT_INT = 6,
2125     CS_STAT_WIS = 7,
2126     CS_STAT_DEX = 8,
2127     CS_STAT_CON = 9,
2128     CS_STAT_CHA = 10,
2129     CS_STAT_EXP = 11,
2130     CS_STAT_LEVEL = 12,
2131     CS_STAT_WC = 13,
2132     CS_STAT_AC = 14,
2133     CS_STAT_DAM = 15,
2134     CS_STAT_ARMOUR = 16,
2135     CS_STAT_SPEED = 17,
2136     CS_STAT_FOOD = 18,
2137     CS_STAT_WEAP_SP = 19,
2138     CS_STAT_RANGE = 20,
2139     CS_STAT_TITLE = 21,
2140     CS_STAT_POW = 22,
2141     CS_STAT_GRACE = 23,
2142     CS_STAT_MAXGRACE = 24,
2143     CS_STAT_FLAGS = 25,
2144     CS_STAT_WEIGHT_LIM = 26,
2145     CS_STAT_EXP64 = 28,
2146     CS_STAT_SPELL_ATTUNE = 29,
2147     CS_STAT_SPELL_REPEL = 30,
2148     CS_STAT_SPELL_DENY = 31,
2149     CS_STAT_RESIST_START = 100,
2150     CS_STAT_RESIST_END = 117,
2151     CS_STAT_RES_PHYS = 100,
2152     CS_STAT_RES_MAG = 101,
2153     CS_STAT_RES_FIRE = 102,
2154     CS_STAT_RES_ELEC = 103,
2155     CS_STAT_RES_COLD = 104,
2156     CS_STAT_RES_CONF = 105,
2157     CS_STAT_RES_ACID = 106,
2158     CS_STAT_RES_DRAIN = 107,
2159     CS_STAT_RES_GHOSTHIT = 108,
2160     CS_STAT_RES_POISON = 109,
2161     CS_STAT_RES_SLOW = 110,
2162     CS_STAT_RES_PARA = 111,
2163     CS_STAT_TURN_UNDEAD = 112,
2164     CS_STAT_RES_FEAR = 113,
2165     CS_STAT_RES_DEPLETE = 114,
2166     CS_STAT_RES_DEATH = 115,
2167     CS_STAT_RES_HOLYWORD = 116,
2168     CS_STAT_RES_BLIND = 117,
2169     CS_STAT_SKILLINFO = 140,
2170     CS_NUM_SKILLS = 50,
2171     SF_FIREON = 0x01,
2172     SF_RUNON = 0x02,
2173     NDI_BLACK = 0,
2174     NDI_WHITE = 1,
2175     NDI_NAVY = 2,
2176     NDI_RED = 3,
2177     NDI_ORANGE = 4,
2178     NDI_BLUE = 5,
2179     NDI_DK_ORANGE = 6,
2180     NDI_GREEN = 7,
2181     NDI_LT_GREEN = 8,
2182     NDI_GREY = 9,
2183     NDI_BROWN = 10,
2184     NDI_GOLD = 11,
2185     NDI_TAN = 12,
2186     NDI_MAX_COLOR = 12,
2187     NDI_COLOR_MASK = 0x1f,
2188     NDI_REPLY = 0x20,
2189     NDI_NOCRATE = 0x40,
2190     NDI_CLEAR = 0x80,
2191     a_none = 0,
2192     a_readied = 1,
2193     a_wielded = 2,
2194     a_worn = 3,
2195     a_active = 4,
2196     a_applied = 5,
2197     F_APPLIED = 0x000F,
2198     F_LOCATION = 0x00F0,
2199     F_UNPAID = 0x0200,
2200     F_MAGIC = 0x0400,
2201     F_CURSED = 0x0800,
2202     F_DAMNED = 0x1000,
2203     F_OPEN = 0x2000,
2204     F_NOPICK = 0x4000,
2205     F_LOCKED = 0x8000,
2206     CF_FACE_NONE = 0,
2207     CF_FACE_BITMAP = 1,
2208     CF_FACE_XPM = 2,
2209     CF_FACE_PNG = 3,
2210     CF_FACE_CACHE = 0x10,
2211     FACE_FLOOR = 0x80,
2212     FACE_COLOR_MASK = 0xf,
2213     UPD_LOCATION = 0x01,
2214     UPD_FLAGS = 0x02,
2215     UPD_WEIGHT = 0x04,
2216     UPD_FACE = 0x08,
2217     UPD_NAME = 0x10,
2218     UPD_ANIM = 0x20,
2219     UPD_ANIMSPEED = 0x40,
2220     UPD_NROF = 0x80,
2221     UPD_SP_MANA = 0x01,
2222     UPD_SP_GRACE = 0x02,
2223     UPD_SP_LEVEL = 0x04,
2224     SOUND_NORMAL = 0,
2225     SOUND_SPELL = 1,
2226    
2227     PICKUP_NOTHING = 0x00000000,
2228    
2229     PICKUP_DEBUG = 0x10000000,
2230     PICKUP_INHIBIT = 0x20000000,
2231     PICKUP_STOP = 0x40000000,
2232     PICKUP_NEWMODE = 0x80000000,
2233    
2234     PICKUP_RATIO = 0x0000000F,
2235    
2236     PICKUP_FOOD = 0x00000010,
2237     PICKUP_DRINK = 0x00000020,
2238     PICKUP_VALUABLES = 0x00000040,
2239     PICKUP_BOW = 0x00000080,
2240    
2241     PICKUP_ARROW = 0x00000100,
2242     PICKUP_HELMET = 0x00000200,
2243     PICKUP_SHIELD = 0x00000400,
2244     PICKUP_ARMOUR = 0x00000800,
2245    
2246     PICKUP_BOOTS = 0x00001000,
2247     PICKUP_GLOVES = 0x00002000,
2248     PICKUP_CLOAK = 0x00004000,
2249     PICKUP_KEY = 0x00008000,
2250    
2251     PICKUP_MISSILEWEAPON = 0x00010000,
2252     PICKUP_ALLWEAPON = 0x00020000,
2253     PICKUP_MAGICAL = 0x00040000,
2254     PICKUP_POTION = 0x00080000,
2255    
2256     PICKUP_SPELLBOOK = 0x00100000,
2257     PICKUP_SKILLSCROLL = 0x00200000,
2258     PICKUP_READABLES = 0x00400000,
2259     PICKUP_MAGIC_DEVICE = 0x00800000,
2260    
2261     PICKUP_NOT_CURSED = 0x01000000,
2262    
2263     PICKUP_JEWELS = 0x02000000,
2264     PICKUP_FLESH = 0x04000000;
2265    
2266     var stat_32bit = [CS_STAT_WEIGHT_LIM,CS_STAT_SPELL_ATTUNE,CS_STAT_SPELL_REPEL,CS_STAT_SPELL_DENY,CS_STAT_EXP];
2267    
2268    
2269     function feed_stats (data,dataAsArray){
2270     var buff = new Buffer(dataAsArray);
2271     buff.position = "stats".length + 1;
2272     while (buff.position < buff.length){
2273     var stat = buff.readUint8();
2274     var value;
2275     if (stat_32bit.contains(stat)){
2276     value = buff.readUint32();
2277     }else if (stat == CS_STAT_SPEED||stat==CS_STAT_WEAP_SP){
2278     value = (1/FLOAT_MULTF) * buff.readUint32();
2279     }else if (stat==CS_STAT_RANGE||stat==CS_STAT_TITLE){
2280     var len = buff.readUint8();
2281     value = buff.readString(len);
2282     }else if (stat == CS_STAT_EXP64){
2283     var hi = buff.readUint32();
2284     var lo = buff.readUint32();
2285     value = hi * Math.pow(2,32) + lo;
2286     }else if (stat>=CS_STAT_SKILLINFO && stat < CS_STAT_SKILLINFO + CS_NUM_SKILLS){
2287     var lvl = buff.readUint8();
2288     var hi = buff.readUint32();
2289     var lo = buff.readUint32();
2290     value = [lvl,hi * Math.pow(2,32) + lo];
2291     }else{
2292     value = buff.readUint16();
2293 sf-demisephi 1.3 if (value > 60000){
2294     value -= 65536;
2295     }
2296 root 1.1 }
2297     myStats [stat] = value;
2298     //stats_update (stat);
2299     }
2300    
2301     return true;
2302     }
2303    
2304     function feed_player (data,dataAsArray){
2305 sf-demisephi 1.4 var buff = new Buffer(dataAsArray);
2306     buff.position ="player ".length;
2307     //my ($tag, $weight, $face, $name) = unpack "NNN C/a", $data;
2308     player.tag = buff.readUint32();
2309     player.weight = buff.readUint32();
2310     player.face = buff.readUint32();
2311     var len = buff.readUint8();
2312     player.name = buff.readString(len);
2313 root 1.1 return false;
2314     }
2315    
2316     function feed_drawinfo (data,dataAsArray){
2317     return false;
2318     }
2319    
2320    
2321    
2322     var tilesInfo = {
2323     listLoading:[],
2324     listLoaded:[],
2325    
2326     isLoading: false,
2327     getImgByFaceNum:function (id){
2328     for (var i=0;i<this.listLoaded.length;++i){
2329     if (this.listLoaded[i].id==id){
2330     return this.listLoaded[i].img;
2331     }
2332     }
2333     return null;
2334     },
2335     isImgLoading : function (id){
2336     for (var i=0;i<this.listLoading.length;++i){
2337     if (this.listLoading[i].id==id){
2338     return true;
2339     }
2340     }
2341     return false;
2342     },
2343     markAsLoaded : function (e){
2344     var i;
2345     for (i=0;i<this.listLoading.length;++i){
2346     if (this.listLoading[i].id == e.id){
2347     this.listLoading.splice(i,1);
2348     break;
2349     }
2350     }
2351    
2352     this.listLoaded.push (e);
2353     this.isLoading = false;
2354     while ((this.listLoading.length>0)&&(this.isLoading==false)){
2355    
2356     var e2 = this.listLoading.pop();
2357     if (e2.src.length > baseURL.length + 1){
2358     this.isLoading = true;
2359     e2.img.src = e2.src;
2360     //alert("loading " + e2.src);
2361     e2.onload = e.onload;
2362     }
2363     }
2364     }
2365     }
2366    
2367     var baseURL = "";
2368     DrawLater = {
2369     list : []
2370     };
2371    
2372    
2373     function imgFromString (s){
2374     var img = $_('img');
2375     img.src = s;
2376     return img;
2377     }
2378    
2379     function need_facenum (num){
2380     var img;
2381    
2382     if (tilesInfo.getImgByFaceNum(num)!=null){
2383     return;
2384     }
2385    
2386     /*if ( img = localStorage.getItem("face_" + num)){
2387    
2388     tilesInfo.listLoaded.push({num:num,data: {img:imgFromString(img)}});
2389     return;
2390     }*/
2391     }
2392     var dx = 0;
2393     var dy = 0;
2394    
2395     function feed_map_scroll (data,dataAsArray,base64data){
2396    
2397     data = data.split(/ /);
2398     data.shift();
2399     dx += parseInt(data.shift());
2400     dy += parseInt(data.shift());
2401    
2402    
2403     }
2404    
2405    
2406     function feed_ix (data,dataAsArray,base64data){
2407    
2408     }
2409    
2410     function arr2bytes(arr){
2411     var s = "";
2412     for (var i=0;i<arr.length;++i){
2413     s+=String.fromCharCode(arr[i]);
2414     }
2415     return s;
2416     }
2417     function bytes2arr(s){
2418     var arr = [];
2419     for (var i=0;i<s.length;++i){
2420     arr.push(s.charCodeAt(i));
2421     }
2422     return arr;
2423     }
2424     function $_(p){
2425     if (document.getElementById(p)!=null){
2426     return document.getElementById(p);
2427     }else{
2428 sf-demisephi 1.3 var ret = document.createElement(p);
2429     unselectable(ret);
2430     return ret;
2431 root 1.1 }
2432     }
2433     var tiles = [];
2434    
2435     function onMessage(evt)
2436     {
2437    
2438     //var data = Widnow.atob(evt.data);
2439     var data = evt.data;
2440     data = (atob(data));
2441    
2442    
2443     //writeToScreen(data);
2444    
2445     var dataAsArray = null;
2446     var patt=/[0-9a-z_]*[^0-9a-z_]/i;
2447     var feed = ""+data.match(patt);
2448     feed=feed.substr(0,feed.length -1);
2449     if (feed=="nul"){
2450     if (data=="newmap"){
2451     feed="newmap";
2452     }else{
2453     return;
2454     }
2455     }
2456     if ((window['feed_' + feed])&&(typeof(window['feed_' + feed])=="function")){
2457     // var retVal = window['feed_' + feed](data,dataAsArray=bytes2arr(evt.data),evt.data);
2458     var retVal = window['feed_' + feed](data,dataAsArray=decode_base64toArray(evt.data),evt.data);
2459     if (!retVal){
2460     //writeToScreen("[" + feed + "] " + data );
2461     //writeToScreen(dataAsArray);
2462     }
2463     }else{
2464     //alert('unhandled "feed_' + feed + '"');
2465    
2466     }
2467    
2468    
2469    
2470     }
2471    
2472     function decode_base64(s) {
2473     var e={},i,k,v=[],r='',w=String.fromCharCode;
2474     var n=[[65,91],[97,123],[48,58],[43,44],[47,48]];
2475    
2476     for(z in n){for(i=n[z][0];i<n[z][1];i++){v.push(w(i));}}
2477     for(i=0;i<64;i++){e[v[i]]=i;}
2478    
2479     for(i=0;i<s.length;i+=72){
2480     var b=0,c,x,l=0,o=s.substring(i,i+72);
2481     for(x=0;x<o.length;x++){
2482     c=e[o.charAt(x)];b=(b<<6)+c;l+=6;
2483     while(l>=8){r+=w((b>>>(l-=8))%256);}
2484     }
2485     }
2486     return r;
2487     }
2488     function decode_base64toArray(s) {
2489     var e={},i,k,v=[],r=[],w=String.fromCharCode;
2490     var n=[[65,91],[97,123],[48,58],[43,44],[47,48]];
2491    
2492     for(z in n){for(i=n[z][0];i<n[z][1];i++){v.push(w(i));}}
2493     for(i=0;i<64;i++){e[v[i]]=i;}
2494    
2495     for(i=0;i<s.length;i+=72){
2496     var b=0,c,x,l=0,o=s.substring(i,i+72);
2497     for(x=0;x<o.length;x++){
2498     c=e[o.charAt(x)];b=(b<<6)+c;l+=6;
2499     while(l>=8){r.push((b>>>(l-=8))%256);}
2500     }
2501     }
2502     return r;
2503     }
2504    
2505    
2506    
2507     function processExtObj (o){
2508     switch (o[0]){
2509     case "channel_info":
2510     channels[o[1].id] = o[1];
2511     channels.list.push (channels[o[1].id]);
2512     channels[o[1].id].index =channels.length;
2513     channels.length+=1;
2514     return true;
2515     default:
2516     return false;
2517     break;
2518     }
2519     }
2520    
2521     function onError(evt)
2522     {
2523     writeToScreen("ERROR!");
2524     }
2525    
2526     function doSend(message)
2527     {
2528     writeToScreen("SENT: " + message);
2529     websocket.send(message);
2530     }
2531    
2532     function writeToScreen(message)
2533     {
2534     var d = new Date();
2535     //Messages.push(new Message(200,(d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() ) + ":" + message));
2536     output.value = d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ":" + message + "\n" + output.value;
2537     }
2538    
2539     function fillFromTemplate(e){
2540     document.getElementById("text").value = e.value;
2541     }
2542    
2543     isMainScriptLoaded = true;
2544    
2545    
2546     //+ Jonas Raoni Soares Silva
2547     //@ http://jsfromhell.com/geral/utf-8 [rev. #1]
2548    
2549     UTF8 = {
2550     encode: function(s){
2551     for(var c, i = -1, l = (s = s.split("")).length, o = String.fromCharCode; ++i < l;
2552     s[i] = (c = s[i].charCodeAt(0)) >= 127 ? o(0xc0 | (c >>> 6)) + o(0x80 | (c & 0x3f)) : s[i]
2553     );
2554     return s.join("");
2555     },
2556     decode: function(s){
2557     for(var a, b, i = -1, l = (s = s.split("")).length, o = String.fromCharCode, c = "charCodeAt"; ++i < l;
2558     ((a = s[i][c](0)) & 0x80) &&
2559     (s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ?
2560     o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "")
2561     );
2562     return s.join("");
2563     }
2564     };