ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/html5client/main.js
Revision: 1.18
Committed: Thu Nov 8 03:08:52 2012 UTC (11 years, 7 months ago) by root
Content type: application/javascript
Branch: MAIN
Changes since 1.17: +0 -3 lines
Log Message:
*** empty log message ***

File Contents

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