ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/deliantra/html5client/main.js
Revision: 1.1
Committed: Sat Nov 3 20:07:06 2012 UTC (13 years, 10 months ago) by root
Content type: application/javascript
Branch: MAIN
Log Message:
initial check.in

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     var keys = {
50     shift: 0,
51     alt: 0,
52     ctrl: 0
53     };
54    
55     var versionInfo = {
56     perlver: "5.014002",
57     clientver: "3.0Af0000000",
58     client: "deliantra",
59     gl_vendor: "NVIDIA Corporation",
60     gl_version: "4.2.0 NVIDIA 302.11",
61     modulever: "1.31",
62     osver: "linux",
63     protver: 1
64     };
65     var expTableFacenum = -1;
66    
67     function appendToBody(e){
68     document.getElementsByTagName("body")[0].appendChild(e);
69     }
70    
71     function getPassword (){
72     return document.getElementById("password").value.trim();
73     }
74    
75     function getLogin (){
76     return document.getElementById("login").value.trim();
77     }
78    
79     function createCommandWindow (){
80     var div = createWindow("command",250,250,stage.stageWidth/2-250/2,stage.stageHeight-250/2);
81     var login = document.createElement("input");
82     login.type = "text";
83     login.placeholder = login.id = "command";
84     login.style.width = "100%";
85    
86     div.appendChild(login);
87    
88     var button = document.createElement("input");
89     button.type = "button";
90     button.value = "execute command";
91     button.style.width = "100%";
92     div.appendChild(button);
93     button.addEventListener("click",function (e){
94     doSend(login.value);
95     document.getElementsByTagName("body")[0].removeChild(div);
96     skipKeyTest = false;
97     })
98     var button = document.createElement("input");
99     button.type = "button";
100     button.value = "cancel";
101     button.style.width = "100%";
102     div.appendChild(button);
103     button.addEventListener("click",function (e){
104     document.getElementsByTagName("body")[0].removeChild(div);
105     skipKeyTest = false;
106     })
107     return div;
108    
109     }
110    
111     var xMapWindow = null;
112     var xFloorWindow = null;
113     var xPlayerWindow = null;
114     var pattern = null;
115     var patternImage = null;
116     var isMainCalled = false;
117     var xInfoWindow = null;
118    
119     var wsUri = "ws://testserver.deliantra.net:13327/ws";
120     //var wsUri = "ws://slashflash.pl:13327/deliantra";
121     //var wsUri = "ws://localhost:13327/deliantra";
122    
123     function createWebSocket(){
124     var websocket = new WebSocket(wsUri);
125     websocket.onopen = function(evt) { onOpen(evt) };
126     websocket.onclose = function(evt) { onClose(evt) };
127     websocket.onmessage = function(evt) { onMessage(evt) };
128     websocket.onerror = function(evt) { onError(evt) };
129     return websocket;
130     }
131    
132    
133    
134     function createLoginWindow(){
135     var div = createWindow("login",260,180,stage.stageWidth/2-250/2,stage.stageHeight/2-250/2).contents;;
136     var login = document.createElement("input");
137     login.type = "text";
138     login.placeholder = login.id = "login";
139     login.style.width = "100%";
140     login.value = "deliantra login";
141     div.appendChild(login);
142     var password = document.createElement("input");
143     password.type = "password";
144     password.value = "";
145     password.style.width = "100%";
146     password.placeholder = password.id = "password";
147     div.appendChild(password);
148    
149     var button = document.createElement("input");
150     button.type = "button";
151     button.value = "logmein";
152     button.style.width = "100%";
153     div.appendChild(button);
154    
155    
156     button.addEventListener("click",function (e){
157     div.parent.style.display="none";
158     xMapWindow.contents.appendChild(canvas);
159     xMapWindow.show(true);
160     xFloorWindow.show(true);
161     ctx.fillStyle = "#000";
162    
163     ctx.font = "10px Courier New,MonoSpace";
164     Messages.push(new Message(100,"'engine' started"));
165     setInterval(draw,1000/5);
166    
167    
168    
169     websocket = new WebSocket(wsUri);
170     websocket.onopen = function(evt) { onOpen(evt) };
171     websocket.onclose = function(evt) { onClose(evt) };
172     websocket.onmessage = function(evt) { onMessage(evt) };
173     websocket.onerror = function(evt) { onError(evt) };
174     })
175     button = document.createElement("input");
176     button.type = "button";
177     button.value = "logmeinasnull";
178     button.style.width = "100%";
179     div.appendChild(button);
180     button.addEventListener("click",function (e){
181     login.value = password.value = "null";
182     div.parent.style.display="none";
183     xMapWindow.contents.appendChild(canvas);
184     xMapWindow.show(true);
185     xFloorWindow.show(true);
186     ctx.fillStyle = "#000";
187     ctx.font = "10px Courier New,MonoSpace";
188     Messages.push(new Message(100,"'engine' started"));
189     setInterval(draw,1000/5);
190    
191     websocket = new WebSocket(wsUri);
192     websocket.onopen = function(evt) { onOpen(evt) };
193     websocket.onclose = function(evt) { onClose(evt) };
194     websocket.onmessage = function(evt) { onMessage(evt) };
195     websocket.onerror = function(evt) { onError(evt) };
196     })
197     button = document.createElement("input");
198     button.type = "button";
199     button.value = "logmeinasNULL";
200     button.style.width = "100%";
201     div.appendChild(button);
202     button.addEventListener("click",function (e){
203     login.value = password.value = "NULL";
204     div.parent.style.display="none";
205     xMapWindow.contents.appendChild(canvas);
206     xMapWindow.show(true);
207     xFloorWindow.show(true);
208     ctx.fillStyle = "#000";
209     ctx.font = "10px Courier New,MonoSpace";
210     Messages.push(new Message(100,"'engine' started"));
211     setInterval(draw,1000/5);
212     websocket = new WebSocket(wsUri);
213     websocket.onopen = function(evt) { onOpen(evt) };
214     websocket.onclose = function(evt) { onClose(evt) };
215     websocket.onmessage = function(evt) { onMessage(evt) };
216     websocket.onerror = function(evt) { onError(evt) };
217     })
218     button = document.createElement("input");
219     button.type = "button";
220     button.value = "logmeinasVOID";
221     button.style.width = "100%";
222     div.appendChild(button);
223     button.addEventListener("click",function (e){
224     login.value = password.value = "VOID";
225     div.parent.style.display="none";
226     xMapWindow.contents.appendChild(canvas);
227     xMapWindow.show(true);
228     xFloorWindow.show(true);
229     ctx.fillStyle = "#000";
230     ctx.font = "10px Courier New,MonoSpace";
231     Messages.push(new Message(100,"'engine' started"));
232     setInterval(draw,1000/5);
233     websocket = new WebSocket(wsUri);
234     websocket.onopen = function(evt) { onOpen(evt) };
235     websocket.onclose = function(evt) { onClose(evt) };
236     websocket.onmessage = function(evt) { onMessage(evt) };
237     websocket.onerror = function(evt) { onError(evt) };
238     })
239     return div.parent;
240    
241    
242     }
243    
244     function main (){
245     if (isMainCalled==true){
246     isMainCalled = true;
247     return;
248     }
249    
250     window.WebSocket = window.WebSocket || window.MozWebSocket;
251    
252     if (window.WebSocket){
253    
254    
255     canvas = document.createElement("canvas");
256     var sw = canvas.width = window.innerWidth-10;
257     var sh = canvas.height =window.innerHeight-10;
258     var dx = Math.floor(sw/64);
259     var dy = Math.floor((sh-120)/64);
260    
261     dx = dy = Math.min(dx,dy);
262     stage = {stageWidth:sw,stageHeight:sh};
263     var logWindow = createWindow("log",stage.stageWidth,120,0,0);
264     xMapWindow = createWindow("map",dx*64+30,dy*64+30,0,120);
265     xMapWindow.style.top = (sh-xMapWindow.height()-20)+"px";
266     xMapWindow.show(false);
267     canvas.width = xMapWindow.width()-10;
268     canvas.height = xMapWindow.height()-25;
269    
270    
271    
272    
273     xFloorWindow = createWindow("floor",Math.floor((sw-xMapWindow.width()-30)/2),350,xMapWindow.width()+30,stage.stageHeight-20-350);
274     xFloorWindow.show(false);
275    
276     xPlayerWindow = createWindow("player",sw - 30,sh-30,10,10);
277     //xPlayerWindow.show(false);
278    
279     xPlayerWindow.contents.innerHTML = "";
280     var buttons = ["Statistics","Skills","SpellBook","Inventory"];
281     var div = document.createElement("div");
282     div.className = "buttons_widnow_content";
283     xPlayerWindow.contents.appendChild(div);
284    
285     for (var i = 0;i<buttons.length;++i){
286     var button = document.createElement("input");
287     button.type="button";
288     button.value = buttons[i] + " (F"+(i+2)+")";
289     button.addEventListener("click",showPlayerTab);
290     div.appendChild(button);
291     }
292     div = document.createElement("div");
293     div.className = "player_widnow_content";
294     xPlayerWindow.contents.appendChild(div);
295    
296     div = document.createElement("div");
297     div.className = "floor_widnow_content";
298     xPlayerWindow.contents.appendChild(div);
299    
300     div = document.createElement("div");
301     div.className = "spellbook_widnow_content";
302     xPlayerWindow.contents.appendChild(div);
303    
304     div = document.createElement("div");
305     div.className = "skills_widnow_content";
306     xPlayerWindow.contents.appendChild(div);
307     hideAllPlayerTabs();
308    
309     xPlayerWindow.show(false);
310     ctx = canvas.getContext('2d');
311    
312     appendToBody(createLoginWindow());
313     window.addEventListener("click",onClick);
314     window.addEventListener("contextmenu",onClick);
315     window.addEventListener("mousemove",onMouseMove);
316     window.addEventListener("mouseup",onMouseUp);
317    
318     //document.getElementsByTagName("body")[0].addEventListener("contextmenu",onClick);
319     //document.addEventListener("contextmenu",onClick);
320    
321     output = document.createElement("textarea");
322    
323     output.style.opacity ="0.3";
324     output.style.filter ="filter:alpha(opacity=30);";
325    
326     output.style.width = "99%"
327     output.style.height = "70%";
328     logWindow.contents.appendChild(output);
329    
330     xInfoWindow = createWindow("info",300,200,-400,-300);
331     xInfoWindow.show(false);
332    
333     }
334     };
335    
336     var currentWindow=null;
337     var currentWindowOffset = {x:0,y:0};
338     var currentWindowResize = false;
339    
340     function showPlayerTab (){
341     var tabName = (this.value).split(" ")[0].toLowerCase();
342    
343     var div;
344    
345     switch (tabName){
346     case "inventory":
347     hideAllPlayerTabs();
348     var content = xPlayerWindow.getElementsByClassName("player_widnow_content")[0];
349     content.style.display = "block";
350     content = xPlayerWindow.getElementsByClassName("floor_widnow_content")[0];
351     content.style.display = "block";
352     updateItemsList();
353     break;
354     case "spellbook":
355    
356     hideAllPlayerTabs();
357     var content = xPlayerWindow.getElementsByClassName("spellbook_widnow_content")[0];
358     content.style.display = "block";
359     updateSpellList();
360     break;
361     case "skills":
362     hideAllPlayerTabs();
363     var content = xPlayerWindow.getElementsByClassName("skills_widnow_content")[0];
364     content.style.display = "block";
365     updateSkillList();
366     default:
367     break;
368     }
369     }
370     var playerTabs = ["player_widnow_content","floor_widnow_content","spellbook_widnow_content","skills_widnow_content"];
371    
372     function hideAllPlayerTabs (){
373     for (var i = 0;i<playerTabs.length;++i){
374     xPlayerWindow.getElementsByClassName(playerTabs[i])[0].style.display="none";
375     }
376     }
377    
378    
379     function updateItemsList(){
380     var content = xPlayerWindow.getElementsByClassName("player_widnow_content")[0];
381    
382    
383     content.innerHTML = "";
384     myItems.each(function (item,i,p){
385     if (isNaN(item.nr_of))
386     return;
387     content.appendChild(div = document.createElement("div"));
388     var img = tilesInfo.getImgByFaceNum(item.face);
389     if (img){
390     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>"
391     }else{
392     div.innerHTML="<div><input type='hidden' value='"+item.itemId+"'/>"+(item.nr_of>1?item.namepl:item.name)+"</div>"
393     }
394    
395     div.addEventListener("click",myInventoryItemClick);
396     div.addEventListener("mouseover",inventoryItemMouseOver);
397     div.addEventListener("mouseout",inventoryItemMouseOut);
398     div.addEventListener("mousemove",inventoryItemMouseMove);
399     },{})
400    
401     content = xPlayerWindow.getElementsByClassName("floor_widnow_content")[0];
402    
403    
404     content.innerHTML = "";
405     floorItems.each(function (item,i,p){
406     if (isNaN(item.nr_of))
407     return;
408     content.appendChild(div = document.createElement("div"));
409     var img = tilesInfo.getImgByFaceNum(item.face);
410     if (img){
411     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>"
412     }else{
413     div.innerHTML="<div><input type='hidden' value='"+item.itemId+"'/>"+(item.nr_of>1?item.namepl:item.name)+"</div>"
414     }
415     div.addEventListener("mouseover",inventoryItemMouseOver);
416     div.addEventListener("mouseout",inventoryItemMouseOut);
417     div.addEventListener("mousemove",inventoryItemMouseMove);
418     div.addEventListener("click",floorInventoryItemClick);
419     },{})
420    
421     }
422    
423     function floorInventoryItemClick(e){
424     var itemId = parseInt(this.getElementsByTagName("input")[0].value);
425    
426     if (!keys.shift){
427     return;
428     }
429    
430     for (var i = 0;i<floorItems.length;++i){
431     if (parseInt(floorItems[i].itemId) == itemId){
432     doSend("command get "+ (floorItems[i].nr_of>1 ? floorItems[i].namepl:floorItems[i].name));
433     }else{
434    
435     }
436     }
437     }
438    
439     function myInventoryItemClick(e){
440     var itemId = parseInt(this.getElementsByTagName("input")[0].value);
441    
442     if (!keys.shift){
443     return;
444     }
445     for (var i = 0;i<myItems.length;++i){
446    
447    
448     if (parseInt(myItems[i].itemId) == itemId){
449     doSend("command drop "+ (myItems[i].nr_of>1 ? myItems[i].namepl:myItems[i].name));
450     }else{
451    
452     }
453     }
454    
455     }
456    
457     function inventoryItemMouseOver(e){
458     this.style.background = "solid";
459     this.style.backgroundColor="white";
460     var itemId = this.getElementsByTagName("input")[0].value;
461     doSend("ex " + itemId);
462    
463     xInfoWindow.show(true);
464     xInfoWindow.style.left = (e.clientX+5)+"px";
465     xInfoWindow.style.top = (e.clientY+5)+"px";
466     }
467    
468     function inventoryItemMouseMove(e){
469    
470     xInfoWindow.style.left = (e.clientX+5)+"px";
471     xInfoWindow.style.top = (e.clientY+5)+"px";
472    
473     }
474    
475     function inventoryItemMouseOut(e){
476     this.style.background = "transparent";
477     xInfoWindow.show(false);
478     }
479    
480     function createWindow(title,width,height,x,y){
481     var windowTemplate = document.getElementById("window_template_container").innerHTML;
482     var div = document.createElement("div");
483     div.innerHTML = windowTemplate;
484    
485     var xwindow = div.getElementsByClassName("window")[0];
486     xwindow.style.left = x+"px";
487     xwindow.style.top = y+"px";
488     xwindow.style.width = width + "px";
489     xwindow.width = function (){
490     return parseInt(xwindow.style.width);
491     };
492    
493     xwindow.height = function (){
494     return parseInt(xwindow.style.height);
495     };
496     xwindow.show = function (b){
497     xwindow.style.display = b?"block":"none";
498     return true;
499     };
500     xwindow.visible = function (b){
501     return xwindow.style.display =="block";
502     };
503     xwindow.style.height = height + "px";
504     xwindow.getElementsByClassName("window_top_title")[0].innerHTML = title;
505     xwindow.getElementsByClassName("window_close")[0].onclick = function (){(xwindow.close());};
506     xwindow.onmousedown = function (e) { if (e.clientY-parseInt(xwindow.style.top)<25){
507     currentWindow = xwindow;
508     currentWindowOffset={x:e.clientX-parseInt(xwindow.style.left),y:e.clientY-parseInt(xwindow.style.top)}
509     }else if (e.clientY-parseInt(xwindow.style.top)>parseInt(xwindow.style.height)-5){
510     if (e.clientX-parseInt(xwindow.style.left)>parseInt(xwindow.style.width)-5){
511     currentWindowResize = true;
512     currentWindow = xwindow;
513     }
514     }
515     };
516     xwindow.contents = xwindow.getElementsByClassName("content")[0];
517     xwindow.contents.parent = xwindow;
518     xwindow.close = function (){document.getElementsByTagName("body")[0].removeChild(xwindow);};
519     appendToBody(xwindow);
520    
521    
522     return xwindow;
523     }
524     function onMouseUp (e){
525    
526     if (currentWindow!=null){
527     currentWindow = null;
528     currentWindowResize = false;
529     }
530     }
531    
532     function onMouseMove (e){
533     stage.mouseX = e.clientX;
534     stage.mouseY = e.clientY;
535     if (currentWindow!=null){
536     if (currentWindowResize == false){
537     currentWindow.style.left = (stage.mouseX-currentWindowOffset.x)+"px";
538     currentWindow.style.top = (stage.mouseY-currentWindowOffset.y)+"px";
539     }else{
540     currentWindow.style.width = (stage.mouseX-parseInt(currentWindow.style.left))+"px";
541     currentWindow.style.height = (stage.mouseY-parseInt(currentWindow.style.top))+"px";
542     }
543     }
544     }
545    
546     function ptInRect(pt,rect){
547     if (pt.x<rect.x) return false;
548     if (pt.y<rect.y) return false;
549     if (pt.x>rect.x+rect.width) return false;
550     if (pt.y>rect.y+rect.height) return false;
551     return true;
552     }
553    
554     function onClick (e){
555     x = e.clientX;
556     y = e.clientY;
557    
558     try{
559     e.preventDefault();
560     }catch (ex){
561    
562     }
563     return false;
564     }
565    
566     function draw(){
567    
568     }
569    
570     function drawStar(ctx,r,x,y){
571     ctx.save();
572     if ( typeof (x) !="undefined" && typeof(y)!="undefined"){
573     ctx.translate ( x , y);
574     }
575    
576     ctx.beginPath()
577     ctx.moveTo(r,0);
578     for (var i=0;i<9;i++){
579     ctx.rotate(Math.PI/5);
580     if(i%2 == 0) {
581     ctx.lineTo((r/0.525731)*0.200811,0);
582     } else {
583     ctx.lineTo(r,0);
584     }
585     }
586     ctx.closePath();
587     ctx.fill();
588     ctx.restore();
589     }
590    
591    
592     function drawChannelBoxTitle (o,x){
593     var textSize = ctx.measureText(o.id);
594    
595     o.rect.x = x;
596     o.rect.y = 15;
597     o.rect.width = textSize.width;
598     o.rect.height = 15;
599    
600     if (o.isActive){
601     ctx.fillStyle = "#fff";
602     ctx.fillRect(x,15,textSize.width,15);
603     ctx.fillStyle = "#f00";
604     ctx.fillText(o.id,x,25);
605     o.newMessages = false;
606     }else{
607     ctx.fillStyle = "#F00";
608    
609     ctx.fillRect(x,15,textSize.width,15);
610     ctx.fillStyle = "#FFF";
611     if (o.newMessages)
612     drawStar(ctx,6,x,15);
613     ctx.fillStyle = "#fff";
614     ctx.fillText(o.id,x,25);
615     }
616     x+=textSize.width + 15;
617     return x;
618     }
619    
620     function drawChannelBox (o){
621     var y = 20;
622     var j=0;
623    
624     if (o.isActive){
625     ctx.fillStyle = "#eee";
626     ctx.fillRect( stage.stageWidth - 420,10+y,400,150);
627    
628     ctx.fillStyle = "#000";
629    
630     for (var i = o.messages.length - 1;i>=0;--i){
631     //ctx.fillText(o.messages[i][2],stage.stageWidth - 420+10,37+y + j*12);
632     y+=fitTextInBox(o.messages[i][2],stage.stageWidth - 420+10,37+y,400,150);
633     }
634     }
635     }
636    
637     function channels_setActive(channel_info){
638     for (var i=0;i<channels.length;++i){
639     if (channels.list[i]==channel_info){
640     channels.list[i].isActive = true;
641     }else{
642     channels.list[i].isActive = false;
643     }
644     }
645     }
646    
647     function channels_addMessage(channelId,o){
648     channels[channelId].messages.push(o);
649     channels[channelId].newMessages = true;
650     }
651    
652    
653     function channels_add(channel_info){
654     channel_info.messages = [];
655     channel_info.index = channels.list.length;
656     channels[channel_info['id']] = channel_info;
657     channels.list.push (channel_info);
658     channels.length+=1;
659     channels_setActive(channel_info);
660    
661     channel_info.rect = { x: 0,y:0,width:0,heigth:0};
662    
663    
664     clickable.push ({element:channel_info,rect:channel_info.rect,onclick:function(e){
665     e.onClick();
666     }});
667    
668     }
669    
670     function fitTextInBox(str,startX,startY,width,height){
671     var words = str.split(/ /);
672     var x = 0;
673     var y = 0;
674     for (var i=0;i<words.length;++i){
675     wordSize = ctx.measureText(words[i]);
676     if (x+wordSize.width<width){
677    
678     }else{
679     x = 0;
680     y += 12;
681     }
682     ctx.fillText(words[i],startX + x,startY + y);
683     x+=wordSize.width + 5;
684     }
685     y += 12;
686     return y;
687     }
688    
689     function Message (ttl,text){
690     this.ttl = ttl;
691     this.text = text;
692     }
693     function onOpen(evt)
694     {
695     writeToScreen("CONNECTED");
696     doSend('version {"clientver":"0.001","client":"deliantra html5 client","osver":"linux","protver":1}');
697     }
698    
699     function onClose(evt)
700     {
701     writeToScreen("DISCONNECTED");
702     }
703    
704     var exti = {
705     nextId : 100,
706     getNextId : function (){
707     return this.nextId++;
708     }
709     };
710    
711     function feed_delitem (data,dataAsArray){
712    
713     var buff=new Buffer(dataAsArray);
714     buff.position = 8;
715    
716     while (buff.position<dataAsArray.length){
717     var itmid = buff.readUint32();
718     removeItem(myItems,itmid);
719     removeItem(floorItems,itmid);
720     }
721    
722     }
723    
724     function removeItem (items,itmid){
725     for (var i=items.length-1;i>=0;--i){
726     if (items[i].itemId == itmid){
727     items.splice(i,1);
728     }
729     }
730     1
731    
732     updateItemsList();
733     }
734    
735     function feed_ex (data,dataAsArray){
736     var buff=new Buffer(dataAsArray);
737     buff.position = 3;
738     var len = buff.unpack_w();
739     var str = buff.readString(len);
740     xInfoWindow.contents.innerHTML = str.split("\n").join("<br/>")+"<small>shift+click - drop,move or pickup item</small>";
741    
742     }
743    
744     function feed_query (data,dataAsArray){
745     switch (String.fromCharCode(dataAsArray[6])){
746     case "0":
747     //var login = prompt("What is your name? (login names are case-sensitive):");
748     doSend("reply " + getLogin())
749     return true;
750     break;
751    
752     case "4":
753     //var password = prompt("What is your password?");
754     doSend("reply " + getPassword());
755    
756     return true
757     break;
758    
759     }
760     return false;
761     }
762    
763    
764     var isRunning = false;
765     var isFiring = false;
766     mapsize = {width: 0,height:0};
767    
768     function feed_version (data,dataAsArray){
769     var smapsize = Math.floor(xMapWindow.width()/64);
770     mapsize.width = mapsize.height = parseInt(smapsize);
771     smapsize = smapsize +"x" + smapsize;
772    
773     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);
774    
775    
776    
777    
778    
779     window.addEventListener("keydown",function (e){
780     if (skipKeyTest){
781     return;
782     }
783     switch(e.keyCode){
784     case 38:
785     //if (keys.ctrl&&!isRunning){
786     // isRunning = true;
787     // doSend("command run north");
788     //doSend("command north")
789     //}
790     //else
791     if (!isFiring&&keys.shift){
792     doSend("command fire");
793     isFiring = true;
794     }
795     doSend("command north");
796     break;
797     case 40:
798     //if (keys.ctrl&&!isRunning){
799     // isRunning = true;
800     // doSend("command run south");
801     // //doSend("command souh")
802     //}
803     //else
804     if (!isFiring&&keys.shift){
805     doSend("command fire");
806     isFiring = true;
807     }
808     doSend("command south");
809     break;
810     case 37:
811     //if (keys.ctrl&&!isRunning){
812     // isRunning = true;
813     // doSend("command run west" );
814     //doSend("command west")
815     //}
816     //else
817     if (!isFiring&&keys.shift){
818     doSend("command fire");
819     isFiring = true;
820     }
821     doSend("command west");
822     break;
823     case 39:
824     if (!isFiring&&keys.shift){
825     doSend("command fire");
826     isFiring = true;
827     }
828     doSend("command east");
829     break;
830     case 49:
831     case 9:
832     xPlayerWindow.show(!xPlayerWindow.visible() );
833     break;
834     /*case 49:
835     skipKeyTest = true;
836     document.getElementsByTagName("body")[0].appendChild(createCommandWindow());
837     break;*/
838    
839     case 32:
840     doSend("command apply");
841     break;
842     case 188:
843     doSend("command get");
844     break;
845     case 16:
846     keys.shift = 1;
847     break;
848     case 18:
849     keys.alt = 1;
850     break;
851     case 17:
852     keys.ctrl = 1;
853     break;
854     default:
855     //messageBox(e.keyCode);
856     break;
857     }
858     try {
859     e.preventDefault();
860     }catch (e){
861    
862     }
863     return false;
864     });
865     window.addEventListener("keyup",function (e){
866     if (skipKeyTest){
867     return;
868     }
869     switch(e.keyCode){
870     case 38:
871     //if (isRunning)
872     //doSend("command run_stop");
873     if (isFiring&&!keys.shift){
874     doSend("command fire_stop");
875     isFiring = false;
876     }
877     break;
878     case 40:
879     if (isFiring&&!keys.shift){
880     doSend("command fire_stop");
881     isFiring = false;
882     }
883     //if (isRunning)
884     //doSend("command run_stop");
885     break;
886     case 37:
887     if (isFiring&&!keys.shift){
888     doSend("command fire_stop");
889     isFiring = false;
890     }
891     //if (isRunning)
892     //doSend("command run_stop");
893     break;
894     case 39:
895     if (isFiring&&!keys.shift){
896     doSend("command fire_stop");
897     isFiring = false;
898     }
899     //if (isRunning)
900     //doSend("command run_stop");
901     break;
902     case 49:
903     break;
904     case 16:
905     keys.shift = 0;
906     break;
907     case 18:
908     keys.alt = 0;
909     break;
910     case 17:
911     keys.ctrl = 0;
912     break;
913     default:
914     //messageBox(e.keyCode);
915     break;
916     }
917     try {
918     e.preventDefault();
919     }catch (e){
920    
921     }
922     //isRunning = false;
923     return false;
924     });
925     channels_add({id:"log"});
926     channels_add({id:"map"});
927     return false;
928     }
929    
930     function feed_setup (data,dataAsArray){
931     doSend('exti ["http_faceurl", ' + exti.getNextId() +']');
932     }
933    
934     //'',
935     //'requestinfo spell_paths',
936    
937    
938     function face2tile (){
939    
940     }
941    
942     function clear_cell (cell){
943     cell.darkness = 256;
944     cell.flags = 0;
945     cell.player =0;
946     cell.tiles = [];
947    
948    
949     return cell;
950     }
951    
952     function map_clear (){
953     Map = [];
954     ctx.clearRect(0,0,stage.stageWidth,stage.stageHeight);
955     }
956    
957     function map_get_cell (x,y){
958     if (typeof(Map[y])=="undefined"){
959     Map[y]= [];
960     for (var j = 0;j<mapsize.width;++j){
961     var cell = {};
962     clear_cell(cell);
963     map_set_cell(j,y,cell);
964    
965     }
966     }
967    
968     if (typeof (Map[y][x]) == "undefined"){
969     Map[y][x] = {};
970     clear_cell(Map[y][x]);
971     }
972     return Map[y][x];
973     }
974    
975     function map_set_cell (x,y,cell){
976     if (typeof(Map[y])=="undefined"){
977     Map[y]= [];
978     for (var j = 0;j<mapsize.width;++j){
979     var cell = map_get_cell(j,y);
980     }
981     }
982    
983    
984     Map[y][x] = cell;
985     return Map[y][x];
986     }
987    
988     function scroll_map (dx,dy){
989     var x,y;
990     var tmpDx = dx;
991     var tmpDy = dy;
992    
993     if (!((dx!=0)||(dy!=0))){
994     return;
995     }
996    
997     while (tmpDy!=0){
998     if (tmpDy<0){
999     var row = Map.pop();
1000     Map.unshift(row);
1001     tmpDy+=1;
1002     }else if (tmpDy>0){
1003     var row = Map.shift();
1004     Map.push(row);
1005     tmpDy-=1;
1006     }
1007     }
1008     for (y=0;y<mapsize.height;++y){
1009    
1010     if (typeof(Map[y])=="undefined"){
1011     Map[y]= [];
1012     for (var j = 0;j<mapsize.width;++j){
1013     var cell = {};
1014     clear_cell(cell);
1015     map_set_cell(j,y,cell);
1016     }
1017     }
1018    
1019     tmpDx = dx;
1020     while (tmpDx!=0){
1021     if (tmpDx<0){
1022     var cell = Map[y].pop();
1023     Map[y].unshift(cell);
1024     tmpDx+=1;
1025     }else if (tmpDx>0){
1026     var cell = Map[y].shift();
1027     Map[y].push(cell);
1028    
1029     tmpDx-=1;
1030     }
1031     }
1032    
1033     }
1034    
1035     }
1036    
1037     function feed_map1a (stringData,data){
1038     scroll_map(dx,dy);
1039     dx = dy = 0;
1040    
1041     var x,y;
1042    
1043     var index = 6;
1044     /*
1045     ctx.fillStyle="rgb(0,0,0)";
1046     ctx.globalAlpha = (256-cell.darkness)/256;
1047     ctx.fillRect (0,0,w,h);
1048     ctx.globalAlpha = 1;
1049     */
1050     while (index<data.length-1){
1051     var flags = (data[index++]<<8) + data[index++];
1052     x = ((flags >> 10) & 63);
1053     y = ((flags >> 4) & 63);
1054    
1055     cell = map_get_cell (x, y);
1056     if (!(flags&15)){
1057     clear_cell(cell);
1058     //ctx.clearRect(x<<6,(y<<6),64,64);
1059     continue;
1060     }
1061    
1062     if (cell.darkness==0){
1063     cell.darkness = 256;
1064     }
1065    
1066     if ((flags & 8)){
1067     do {
1068     var cmd = 0;
1069     var ext = 0;
1070    
1071     ext = data[index++];
1072     cmd = ext & 0x7f;
1073     if (cmd<4){
1074     cell.darkness = 255 - ext * 64 + 1;
1075     }else if (cmd == 5){
1076     cell.stat_width = 1;
1077     cell.stat_hp = data[index++];
1078     }else if (cmd == 6) {// monster width{
1079     cell.stat_width = data[index++] + 1;
1080     }else if (cmd == 0x47){
1081     if (data[index] == 1) cell.player = data [index + 1];
1082     else if (data[index] == 2) cell.player = data [index + 2] + (data [index + 1] << 8);
1083     else if (data[index] == 3) cell.player = data [index + 3] + (data [index + 2] << 8) + (data [index + 1] << 16);
1084     else if (data[index] == 4) cell.player = data [index + 4] + (data [index + 3] << 8) + (data [index + 2] << 16) + (data [index + 1] << 24);
1085    
1086     index += data[index] + 1;
1087     }
1088     else if (cmd == 8) // cell flags
1089     cell.flags = data[index++];
1090     else if (ext & 0x40) // unknown, multibyte => skip
1091     index+= data[index]+1;
1092     else
1093     index++;
1094     }while (ext&0x80);
1095     }
1096    
1097    
1098    
1099     for (var z = 0; z <= 2; ++z)
1100     if ((flags & (4 >> z)))
1101     {
1102     var face = (data [index++] << 8) + data [index++];
1103     need_facenum (face);
1104     cell.tiles [z] = face;
1105     }
1106    
1107    
1108     }
1109     drawMap();
1110     return true;
1111    
1112     }
1113    
1114     function drawMap(){
1115    
1116     timoutH = 0;
1117     ctx.clearRect(0,0,stage.stageWidth,stage.stageHeight);
1118     ctx.fillStyle = "#000";
1119     ctx.fillRect(0,0,canvas.width,canvas.height);
1120    
1121     for (var i = 0;i<mapsize.height;++i){
1122     for (var j=0;j<mapsize.width;++j){
1123     var x = j<<6;
1124     var y = i<<6;
1125     var cellx = map_get_cell(j,i);
1126     for (var z=0;z<=2;++z){
1127     if (!cellx.tiles[z])
1128     continue;
1129     var img = tilesInfo.getImgByFaceNum(cellx.tiles[z]);
1130     if (img){
1131     ctx.drawImage(img,x,y);
1132     }else{
1133    
1134     }
1135     }
1136     }
1137     }
1138     }
1139    
1140     function feed_ext (data,dataAsArray){
1141    
1142    
1143    
1144    
1145    
1146     if (data.indexOf ("channel_info")>0){
1147     var channel_info = JSON.parse(data.substr(4))[1];
1148     channels_add(channel_info);
1149     return true;
1150     }else{
1151    
1152     var o = JSON.parse(data.substr(4));
1153     var replyID = parseInt(o[0].split("-")[1]);
1154    
1155     if (replyID == 100){
1156     baseURL = o[1];
1157     baseURL = "http://testserver.deliantra.net:13327" + baseURL + "";
1158     doSend('requestinfo skill_info');
1159    
1160     }else if (replyID==101){
1161     expTableFacenum = parseInt(o[1]);
1162     doSend("addme");
1163     }
1164     else{
1165    
1166     }
1167    
1168    
1169     writeToScreen(data);
1170     }
1171     return false;
1172     }
1173     var Constants = {
1174     a_none : 0,
1175     a_readied : 1,
1176     a_wielded : 2,
1177     a_worn : 3,
1178     a_active : 4,
1179     a_applied : 5,
1180     F_APPLIED : 0x000F,
1181     F_LOCATION : 0x00F0,
1182     F_UNPAID : 0x0200,
1183     F_MAGIC : 0x0400,
1184     F_CURSED : 0x0800,
1185     F_DAMNED : 0x1000,
1186     F_OPEN : 0x2000,
1187     F_NOPICK : 0x4000,
1188     F_LOCKED : 0x8000
1189     };
1190     function Buffer (dataArray){
1191     this.buffer = dataArray;
1192     this.position = 0;
1193     this.length = dataArray.length;
1194     return this;
1195     }
1196    
1197     Buffer.prototype.unpack_w = function (){
1198     var num = 0;
1199     var byte = 0;
1200     do {
1201     num*=128;
1202     byte = parseInt(this.buffer[this.position++]);
1203     num+=byte&0x7f;
1204     }while (byte&0x80);
1205     return num;
1206     };
1207    
1208     Buffer.prototype.readUint32 = function (){
1209     var ret = 0;
1210     for (var i=0;i<4;++i){
1211     ret*=256;
1212     ret+=this.buffer[this.position++];
1213     }
1214     return ret;
1215     };
1216    
1217     Buffer.prototype.readUint8 = function (){
1218     var ret = 0;
1219     for (var i=0;i<1;++i){
1220     ret*=256;
1221     ret+=parseInt(this.buffer[this.position++]);
1222     }
1223     return ret;
1224     };
1225    
1226     Buffer.prototype.readUint16 = function (){
1227     var ret = 0;
1228     for (var i=0;i<2;++i){
1229     ret*=256;
1230     ret+=this.buffer[this.position++];
1231     }
1232     return ret;
1233     };
1234    
1235     Buffer.prototype.readString = function (len){
1236     var ret = "";
1237    
1238     if ( typeof (len) != "undefined"){
1239     for (var i=0;i<len;++i){
1240     ret+=String.fromCharCode(this.buffer[this.position++]);
1241     }
1242     }else{
1243    
1244     while (this.buffer[this.position]!=0){
1245     ret+=String.fromCharCode(this.buffer[this.position++]);
1246     }
1247     }
1248    
1249     return ret;
1250     };
1251    
1252    
1253    
1254     function unselectable (target){
1255     target.setAttribute('unselectable','on');
1256     if (typeof target.onselectstart != "undefined") //IE route
1257     target.onselectstart = function() { return false }
1258     else if (typeof target.style.MozUserSelect != "undefined") //Firefox route
1259     target.style.MozUserSelect = "none"
1260     else //All other route (ie: Opera)
1261     target.onmousedown = function() { return false }
1262     }
1263    
1264     function Item (){
1265     this.itemId = 0;
1266     this.flags = 0;
1267     this.weight = 0;
1268     this.face = 0;
1269     this.name = "";
1270     this.namepl = "";
1271     this.animation_id=0;
1272     this.anim_speed=0;
1273     this.nr_of=0;
1274     this.clientType=0;
1275     }
1276    
1277    
1278     function feed_replyinfo (data){
1279     doSend('exti ["resource",'+exti.getNextId()+',"exp_table"]');
1280    
1281     data = data.substr("replyinfo ".length);
1282     var type = data.substr(0,data.indexOf("\n")).trim();
1283     if (type == "skill_info"){
1284     data = data.substr(type.length+1).split("\n");
1285     for (var i=0;i<data.length;++i){
1286     if (data[i].indexOf(":")){
1287     data[i] = (""+data[i]).split(":");
1288     skillNames[parseInt(data[i][0])] = data[i][1];
1289    
1290     }
1291    
1292    
1293     }
1294     }
1295    
1296     }
1297    
1298     function feed_item2 (data,dataAsArray){
1299     var buff = new Buffer(dataAsArray);
1300     buff.position = 6;
1301     var container = buff.readUint32();
1302    
1303     while (buff.position<buff.length){
1304     var item = new Item();
1305    
1306     item.itemId = buff.readUint32();
1307    
1308     item.flags = buff.readUint32();
1309     item.weight = buff.readUint32();
1310     item.face = buff.readUint32();
1311     var len = (buff.readUint8());
1312    
1313     var names = (buff.readString(len)).split(String.fromCharCode(0));
1314     item.name = names[0];
1315     item.namepl = "";
1316    
1317     if (names.length>1)
1318     item.namepl = names[1];
1319    
1320     item.animation_id = buff.readUint16();
1321     item.anim_speed = buff.readUint8();
1322     item.nr_of = buff.readUint32();
1323     item.clientType = buff.readUint16();
1324     if (container!=0){
1325     myItems.push (item);
1326     }else{
1327     floorItems.push(item);
1328     }
1329     }
1330     if (container==0){
1331     xFloorWindow.contents.innerHTML="";
1332     for (var i=0;i<floorItems.length;++i){
1333     var item = floorItems[i];
1334     if (item.itemId==null||isNaN(item.itemId))
1335     continue;
1336     var img = tilesInfo.getImgByFaceNum(item.face);
1337     var div = document.createElement("div");
1338     xFloorWindow.contents.appendChild(div);
1339     if (img){
1340     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>"
1341     }else{
1342     div.innerHTML+="<div><input type='hidden' value='"+item.itemId+"'/>"+(item.nr_of>1?item.namepl:item.name)+"</div>"
1343     }
1344    
1345     div.addEventListener("click",floorInventoryItemClick);
1346     div.addEventListener("mouseover",inventoryItemMouseOver);
1347     div.addEventListener("mouseout",inventoryItemMouseOut);
1348     div.addEventListener("mousemove",inventoryItemMouseMove);
1349    
1350     }
1351    
1352    
1353     }
1354     updateItemsList();
1355     return false;
1356     }
1357    
1358     function Spell (){
1359    
1360     }
1361    
1362     function updateSpellList (){
1363     var content = xPlayerWindow.getElementsByClassName("spellbook_widnow_content")[0];
1364     content.style.display = "block";
1365    
1366     content.innerHTML = "";
1367     var table;
1368     var tr;
1369     var td;
1370    
1371     content.appendChild(table = document.createElement("table"));
1372     table.style.width="100%";
1373     if (mySpells.length<=0){
1374     return;
1375     }
1376     table.appendChild(tr = document.createElement("tr"));
1377     item = mySpells[0];
1378     for (s in item){
1379    
1380     if ((typeof(item[s])==typeof(1))||(typeof(item[s])==typeof(""))){
1381     if (s=="tag"){
1382    
1383     }else if (s=="message"){
1384    
1385     }else if (s=="face"){
1386     tr.appendChild(td=document.createElement("td"));
1387     td.innerHTML = s;
1388     }else{
1389     tr.appendChild(td=document.createElement("td"));
1390     td.innerHTML = s;
1391     }
1392     }
1393    
1394     }
1395    
1396    
1397     mySpells.each(function (item,i,p){
1398    
1399     table.appendChild(tr = document.createElement("tr"));
1400     tr.index = i;
1401     var img = tilesInfo.getImgByFaceNum(item.face);
1402    
1403     var s;
1404     for (s in item){
1405     if (isNaN(item['face'])){
1406     continue;
1407     }
1408    
1409     if ((typeof(item[s])==typeof(1))||(typeof(item[s])==typeof(""))){
1410     if (s=="tag"){
1411     tr.tag = item[s];
1412     }else if (s=="message"){
1413     tr.message = item[s];
1414     }else if (s=="face"){
1415     tr.appendChild(td=document.createElement("td"));
1416     td.innerHTML = "<img src='"+img.src+"' alt='' style='width:32px;'/>";
1417     }else{
1418     tr.appendChild(td=document.createElement("td"));
1419     td.innerHTML = item[s];
1420     }
1421     }
1422    
1423     }
1424     tr.addEventListener("click",mySpellItemClick);
1425     tr.addEventListener("mouseover",SpellItemMouseOver);
1426     tr.addEventListener("mouseout",SpellItemMouseOut);
1427     tr.addEventListener("mousemove",SpellItemMouseMove);
1428    
1429     /*if (img){
1430     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>"
1431     }else{
1432     div.innerHTML="<div><input type='hidden' value='"+item.itemId+"'/>"+(item.nr_of>1?item.namepl:item.name)+"</div>"
1433     }*/
1434    
1435    
1436     },{})
1437    
1438    
1439     }
1440     function updateSkillList (){
1441     var content = xPlayerWindow.getElementsByClassName("skills_widnow_content")[0];
1442    
1443    
1444     content.innerHTML = "";
1445     var tableLeft;
1446     var tableRight;
1447     var tr;
1448     var td;
1449    
1450     content.appendChild(tableLeft = document.createElement("table"));
1451     tableLeft.style.width="45%";
1452     tableLeft.style.float = "left";
1453     content.appendChild(tableRight = document.createElement("table"));
1454     tableRight.style.width="45%";
1455     tableRight.style.float = "right";
1456    
1457     var j=0;
1458    
1459     for (i=CS_STAT_SKILLINFO;i<CS_STAT_SKILLINFO+CS_NUM_SKILLS;++i){
1460    
1461     if (!myStats[i]){
1462     continue;
1463     }
1464     var table = j%2==0 ? tableLeft : tableRight;
1465    
1466     table.appendChild(tr = document.createElement("tr"));
1467     tr.index = i;
1468    
1469    
1470     tr.appendChild(td=document.createElement("td"));
1471     td.innerHTML = skillNames[i];
1472    
1473     for (var k =0 ;k<myStats[i].length;++k){
1474    
1475     tr.appendChild(td=document.createElement("td"));
1476     td.innerHTML = myStats[i][k];
1477    
1478     }
1479     tr.appendChild(td=document.createElement("td"));
1480     td.innerHTML = Math.floor(myStats[i][1]/expTable[parseInt(myStats[i][0])])*100 + "%";
1481     /*tr.addEventListener("click",mySpellItemClick);
1482     tr.addEventListener("mouseover",SpellItemMouseOver);
1483     tr.addEventListener("mouseout",SpellItemMouseOut);
1484     tr.addEventListener("mousemove",SpellItemMouseMove);
1485     */
1486     ++j;
1487     };
1488    
1489    
1490     }
1491    
1492     function mySpellItemClick(e){
1493     if (keys.ctrl){
1494     doSend("command invoke " + mySpells[this.index].name);
1495     }else if (keys.shift){
1496     doSend("command cast " + mySpells[this.index].name);
1497     }
1498     }
1499    
1500    
1501     function SpellItemMouseOver(e){
1502     this.style.background = "solid";
1503     this.style.backgroundColor="white";
1504    
1505     xInfoWindow.contents.innerHTML = this.message + "<small><br/>shift-click to cast<br/>ctrl-click to invoke</small>";
1506     xInfoWindow.show(true);
1507     xInfoWindow.style.left = (e.clientX+5)+"px";
1508     xInfoWindow.style.top = (e.clientY+5)+"px";
1509     }
1510    
1511     function SpellItemMouseMove(e){
1512    
1513     xInfoWindow.style.left = (e.clientX+5)+"px";
1514     xInfoWindow.style.top = (e.clientY+5)+"px";
1515    
1516     }
1517    
1518     function SpellItemMouseOut(e){
1519     this.style.background = "transparent";
1520     xInfoWindow.show(false);
1521     }
1522    
1523    
1524     function feed_addspell (data,dataAsArray){
1525    
1526     var buff = new Buffer(dataAsArray);
1527     buff.position = data.indexOf(" ")+1;
1528     while (buff.position<buff.length){
1529     spell=new Spell();
1530    
1531     spell.tag = buff.readUint32();
1532    
1533     spell.minLevel = buff.readUint16();
1534    
1535     spell.castingTime = buff.readUint16();
1536    
1537     spell.mana = buff.readUint16();
1538    
1539     spell.grace = buff.readUint16();
1540    
1541     spell.level = buff.readUint16();
1542    
1543     spell.skill = buff.readUint8();
1544    
1545     spell.path = buff.readUint32();
1546    
1547     spell.face = buff.readUint32();
1548     var len = buff.readUint8();
1549     spell.name = buff.readString(len);
1550     len = buff.readUint16();
1551     spell.message = buff.readString(len);
1552     mySpells.push(spell);
1553     }
1554    
1555    
1556     }
1557    
1558     function feed_delinv (data,dataAsArray){
1559     var container = parseInt(data.split(" ")[1]);
1560     if (container!=0){
1561     myItems = [];
1562     }else{
1563     floorItems = [];
1564     }
1565     return false;
1566     }
1567    
1568     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];
1569    
1570     function feed_fx (data,dataAsArray){
1571    
1572     var buff = new Buffer(dataAsArray);
1573     buff.position = 3;
1574     var ignore = true;
1575     while (buff.position<buff.length){
1576     var id = buff.unpack_w();
1577     var len = buff.readUint8();
1578     var nameX = "";
1579     for (var i = 0;i<len;++i){
1580     var c = parseInt(buff.readUint8());
1581     var out="";
1582     out+="0123456789abcdef"[c&0xf];
1583     out= "0123456789abcdef"[c>>4]+out;
1584     nameX+=out;
1585     }
1586     var img = document.createElement("img");
1587    
1588     var e;
1589     if (tilesInfo.getImgByFaceNum(id)){
1590    
1591     }else{
1592     if (nameX.length>3){
1593     if (nameX=="f66e1bc0a5662e59be0253a84ee06c"){
1594     var req = new XMLHttpRequest();
1595     req.open('GET', baseURL+""+nameX, false);
1596     req.send(null);
1597     if(req.status == 200)
1598     messageBox(req.responseText);
1599     /*
1600     var iframe = $_("iframe");
1601     appendToBody(iframe);
1602     iframe.style.display = "none";
1603     iframe.onload = function (){
1604     var doc = null;
1605     try{
1606     doc = iframe.document || iframe.contentDocument || iframe.contentWindow && iframe.contentWindow.document || null;
1607     } catch(err) {
1608     messageBox('error: ' + err.description);
1609     }
1610     messageBox (doc.body.innerHTML);
1611     }
1612     iframe.src =baseURL+""+nameX;*/
1613    
1614    
1615     }else{
1616     tilesInfo.listLoading.push (e={name:nameX,id:id,img:img,src:baseURL+""+nameX});
1617     e.img.parent = e;
1618     e.img.onload = function (){tilesInfo.markAsLoaded(this.parent);}
1619     if (!tilesInfo.isLoading){
1620    
1621     tilesInfo.isLoading = true;
1622     e.img.src = e.src;
1623     //alert("loading: " + e.src);
1624     }
1625     }
1626     }else{
1627     //alert ("face num " + id + " has name len :" + len + " !!!!");
1628     //prompt("",dataAsArray);
1629     }
1630     }
1631     }
1632    
1633     return false;
1634     }
1635    
1636    
1637     function feed_newmap (data,dataAsArray){
1638     //messageBox("newmap");
1639     map_clear();
1640     }
1641    
1642     function feed_mapinfo (data,dataAsArray){
1643     var parts = data.split(/ /);
1644     //map_clear();
1645     return false;
1646     }
1647    
1648    
1649     function feed_msg (data,dataAsArray){
1650     var o = null;
1651     if (data.indexOf("[")>0){
1652     o = JSON.parse(data.substr(4));
1653    
1654     channels_addMessage(o[1],o)
1655     return true;
1656     }
1657     return false;
1658     }
1659    
1660    
1661     function feed_anim (data,dataAsArray){
1662     return false;
1663     }
1664    
1665     /*
1666     CONSTANTS
1667     */
1668    
1669     var TICK = 0.120,
1670     CS_QUERY_YESNO = 0x1,
1671     CS_QUERY_SINGLECHAR = 0x2,
1672     CS_QUERY_HIDEINPUT = 0x4,
1673     CS_SAY_NORMAL = 0x1,
1674     CS_SAY_SHOUT = 0x2,
1675     CS_SAY_GSAY = 0x4,
1676     FLOAT_MULTI = 100000,
1677     FLOAT_MULTF = 100000.0,
1678     CS_STAT_HP = 1,
1679     CS_STAT_MAXHP = 2,
1680     CS_STAT_SP = 3,
1681     CS_STAT_MAXSP = 4,
1682     CS_STAT_STR = 5,
1683     CS_STAT_INT = 6,
1684     CS_STAT_WIS = 7,
1685     CS_STAT_DEX = 8,
1686     CS_STAT_CON = 9,
1687     CS_STAT_CHA = 10,
1688     CS_STAT_EXP = 11,
1689     CS_STAT_LEVEL = 12,
1690     CS_STAT_WC = 13,
1691     CS_STAT_AC = 14,
1692     CS_STAT_DAM = 15,
1693     CS_STAT_ARMOUR = 16,
1694     CS_STAT_SPEED = 17,
1695     CS_STAT_FOOD = 18,
1696     CS_STAT_WEAP_SP = 19,
1697     CS_STAT_RANGE = 20,
1698     CS_STAT_TITLE = 21,
1699     CS_STAT_POW = 22,
1700     CS_STAT_GRACE = 23,
1701     CS_STAT_MAXGRACE = 24,
1702     CS_STAT_FLAGS = 25,
1703     CS_STAT_WEIGHT_LIM = 26,
1704     CS_STAT_EXP64 = 28,
1705     CS_STAT_SPELL_ATTUNE = 29,
1706     CS_STAT_SPELL_REPEL = 30,
1707     CS_STAT_SPELL_DENY = 31,
1708     CS_STAT_RESIST_START = 100,
1709     CS_STAT_RESIST_END = 117,
1710     CS_STAT_RES_PHYS = 100,
1711     CS_STAT_RES_MAG = 101,
1712     CS_STAT_RES_FIRE = 102,
1713     CS_STAT_RES_ELEC = 103,
1714     CS_STAT_RES_COLD = 104,
1715     CS_STAT_RES_CONF = 105,
1716     CS_STAT_RES_ACID = 106,
1717     CS_STAT_RES_DRAIN = 107,
1718     CS_STAT_RES_GHOSTHIT = 108,
1719     CS_STAT_RES_POISON = 109,
1720     CS_STAT_RES_SLOW = 110,
1721     CS_STAT_RES_PARA = 111,
1722     CS_STAT_TURN_UNDEAD = 112,
1723     CS_STAT_RES_FEAR = 113,
1724     CS_STAT_RES_DEPLETE = 114,
1725     CS_STAT_RES_DEATH = 115,
1726     CS_STAT_RES_HOLYWORD = 116,
1727     CS_STAT_RES_BLIND = 117,
1728     CS_STAT_SKILLINFO = 140,
1729     CS_NUM_SKILLS = 50,
1730     SF_FIREON = 0x01,
1731     SF_RUNON = 0x02,
1732     NDI_BLACK = 0,
1733     NDI_WHITE = 1,
1734     NDI_NAVY = 2,
1735     NDI_RED = 3,
1736     NDI_ORANGE = 4,
1737     NDI_BLUE = 5,
1738     NDI_DK_ORANGE = 6,
1739     NDI_GREEN = 7,
1740     NDI_LT_GREEN = 8,
1741     NDI_GREY = 9,
1742     NDI_BROWN = 10,
1743     NDI_GOLD = 11,
1744     NDI_TAN = 12,
1745     NDI_MAX_COLOR = 12,
1746     NDI_COLOR_MASK = 0x1f,
1747     NDI_REPLY = 0x20,
1748     NDI_NOCRATE = 0x40,
1749     NDI_CLEAR = 0x80,
1750     a_none = 0,
1751     a_readied = 1,
1752     a_wielded = 2,
1753     a_worn = 3,
1754     a_active = 4,
1755     a_applied = 5,
1756     F_APPLIED = 0x000F,
1757     F_LOCATION = 0x00F0,
1758     F_UNPAID = 0x0200,
1759     F_MAGIC = 0x0400,
1760     F_CURSED = 0x0800,
1761     F_DAMNED = 0x1000,
1762     F_OPEN = 0x2000,
1763     F_NOPICK = 0x4000,
1764     F_LOCKED = 0x8000,
1765     CF_FACE_NONE = 0,
1766     CF_FACE_BITMAP = 1,
1767     CF_FACE_XPM = 2,
1768     CF_FACE_PNG = 3,
1769     CF_FACE_CACHE = 0x10,
1770     FACE_FLOOR = 0x80,
1771     FACE_COLOR_MASK = 0xf,
1772     UPD_LOCATION = 0x01,
1773     UPD_FLAGS = 0x02,
1774     UPD_WEIGHT = 0x04,
1775     UPD_FACE = 0x08,
1776     UPD_NAME = 0x10,
1777     UPD_ANIM = 0x20,
1778     UPD_ANIMSPEED = 0x40,
1779     UPD_NROF = 0x80,
1780     UPD_SP_MANA = 0x01,
1781     UPD_SP_GRACE = 0x02,
1782     UPD_SP_LEVEL = 0x04,
1783     SOUND_NORMAL = 0,
1784     SOUND_SPELL = 1,
1785    
1786     PICKUP_NOTHING = 0x00000000,
1787    
1788     PICKUP_DEBUG = 0x10000000,
1789     PICKUP_INHIBIT = 0x20000000,
1790     PICKUP_STOP = 0x40000000,
1791     PICKUP_NEWMODE = 0x80000000,
1792    
1793     PICKUP_RATIO = 0x0000000F,
1794    
1795     PICKUP_FOOD = 0x00000010,
1796     PICKUP_DRINK = 0x00000020,
1797     PICKUP_VALUABLES = 0x00000040,
1798     PICKUP_BOW = 0x00000080,
1799    
1800     PICKUP_ARROW = 0x00000100,
1801     PICKUP_HELMET = 0x00000200,
1802     PICKUP_SHIELD = 0x00000400,
1803     PICKUP_ARMOUR = 0x00000800,
1804    
1805     PICKUP_BOOTS = 0x00001000,
1806     PICKUP_GLOVES = 0x00002000,
1807     PICKUP_CLOAK = 0x00004000,
1808     PICKUP_KEY = 0x00008000,
1809    
1810     PICKUP_MISSILEWEAPON = 0x00010000,
1811     PICKUP_ALLWEAPON = 0x00020000,
1812     PICKUP_MAGICAL = 0x00040000,
1813     PICKUP_POTION = 0x00080000,
1814    
1815     PICKUP_SPELLBOOK = 0x00100000,
1816     PICKUP_SKILLSCROLL = 0x00200000,
1817     PICKUP_READABLES = 0x00400000,
1818     PICKUP_MAGIC_DEVICE = 0x00800000,
1819    
1820     PICKUP_NOT_CURSED = 0x01000000,
1821    
1822     PICKUP_JEWELS = 0x02000000,
1823     PICKUP_FLESH = 0x04000000;
1824    
1825     var stat_32bit = [CS_STAT_WEIGHT_LIM,CS_STAT_SPELL_ATTUNE,CS_STAT_SPELL_REPEL,CS_STAT_SPELL_DENY,CS_STAT_EXP];
1826    
1827    
1828     function feed_stats (data,dataAsArray){
1829     var buff = new Buffer(dataAsArray);
1830     buff.position = "stats".length + 1;
1831     while (buff.position < buff.length){
1832     var stat = buff.readUint8();
1833     var value;
1834     if (stat_32bit.contains(stat)){
1835     value = buff.readUint32();
1836     }else if (stat == CS_STAT_SPEED||stat==CS_STAT_WEAP_SP){
1837     value = (1/FLOAT_MULTF) * buff.readUint32();
1838     }else if (stat==CS_STAT_RANGE||stat==CS_STAT_TITLE){
1839     var len = buff.readUint8();
1840     value = buff.readString(len);
1841     }else if (stat == CS_STAT_EXP64){
1842     var hi = buff.readUint32();
1843     var lo = buff.readUint32();
1844     value = hi * Math.pow(2,32) + lo;
1845     }else if (stat>=CS_STAT_SKILLINFO && stat < CS_STAT_SKILLINFO + CS_NUM_SKILLS){
1846     var lvl = buff.readUint8();
1847     var hi = buff.readUint32();
1848     var lo = buff.readUint32();
1849     value = [lvl,hi * Math.pow(2,32) + lo];
1850     }else{
1851     value = buff.readUint16();
1852     }
1853     myStats [stat] = value;
1854     //stats_update (stat);
1855     }
1856    
1857     return true;
1858     }
1859    
1860     function feed_player (data,dataAsArray){
1861     return false;
1862     }
1863    
1864     function feed_drawinfo (data,dataAsArray){
1865     return false;
1866     }
1867    
1868    
1869    
1870     var tilesInfo = {
1871     listLoading:[],
1872     listLoaded:[],
1873    
1874     isLoading: false,
1875     getImgByFaceNum:function (id){
1876     for (var i=0;i<this.listLoaded.length;++i){
1877     if (this.listLoaded[i].id==id){
1878     return this.listLoaded[i].img;
1879     }
1880     }
1881     return null;
1882     },
1883     isImgLoading : function (id){
1884     for (var i=0;i<this.listLoading.length;++i){
1885     if (this.listLoading[i].id==id){
1886     return true;
1887     }
1888     }
1889     return false;
1890     },
1891     markAsLoaded : function (e){
1892     var i;
1893     for (i=0;i<this.listLoading.length;++i){
1894     if (this.listLoading[i].id == e.id){
1895     this.listLoading.splice(i,1);
1896     break;
1897     }
1898     }
1899    
1900     this.listLoaded.push (e);
1901     this.isLoading = false;
1902     while ((this.listLoading.length>0)&&(this.isLoading==false)){
1903    
1904     var e2 = this.listLoading.pop();
1905     if (e2.src.length > baseURL.length + 1){
1906     this.isLoading = true;
1907     e2.img.src = e2.src;
1908     //alert("loading " + e2.src);
1909     e2.onload = e.onload;
1910     }
1911     }
1912     }
1913     }
1914    
1915     var baseURL = "";
1916     DrawLater = {
1917     list : []
1918     };
1919    
1920    
1921     function imgFromString (s){
1922     var img = $_('img');
1923     img.src = s;
1924     return img;
1925     }
1926    
1927     function need_facenum (num){
1928     var img;
1929    
1930     if (tilesInfo.getImgByFaceNum(num)!=null){
1931     return;
1932     }
1933    
1934     /*if ( img = localStorage.getItem("face_" + num)){
1935    
1936     tilesInfo.listLoaded.push({num:num,data: {img:imgFromString(img)}});
1937     return;
1938     }*/
1939     }
1940     var dx = 0;
1941     var dy = 0;
1942    
1943     function feed_map_scroll (data,dataAsArray,base64data){
1944    
1945     data = data.split(/ /);
1946     data.shift();
1947     dx += parseInt(data.shift());
1948     dy += parseInt(data.shift());
1949    
1950    
1951     }
1952    
1953    
1954     function feed_ix (data,dataAsArray,base64data){
1955    
1956     }
1957    
1958     function arr2bytes(arr){
1959     var s = "";
1960     for (var i=0;i<arr.length;++i){
1961     s+=String.fromCharCode(arr[i]);
1962     }
1963     return s;
1964     }
1965     function bytes2arr(s){
1966     var arr = [];
1967     for (var i=0;i<s.length;++i){
1968     arr.push(s.charCodeAt(i));
1969     }
1970     return arr;
1971     }
1972     function $_(p){
1973     if (document.getElementById(p)!=null){
1974     return document.getElementById(p);
1975     }else{
1976     return document.createElement(p);
1977     }
1978     }
1979     var tiles = [];
1980    
1981     function onMessage(evt)
1982     {
1983    
1984     //var data = Widnow.atob(evt.data);
1985     var data = evt.data;
1986     data = (atob(data));
1987    
1988    
1989     //writeToScreen(data);
1990    
1991     var dataAsArray = null;
1992     var patt=/[0-9a-z_]*[^0-9a-z_]/i;
1993     var feed = ""+data.match(patt);
1994     feed=feed.substr(0,feed.length -1);
1995     if (feed=="nul"){
1996     if (data=="newmap"){
1997     feed="newmap";
1998     }else{
1999     return;
2000     }
2001     }
2002     if ((window['feed_' + feed])&&(typeof(window['feed_' + feed])=="function")){
2003     // var retVal = window['feed_' + feed](data,dataAsArray=bytes2arr(evt.data),evt.data);
2004     var retVal = window['feed_' + feed](data,dataAsArray=decode_base64toArray(evt.data),evt.data);
2005     if (!retVal){
2006     //writeToScreen("[" + feed + "] " + data );
2007     //writeToScreen(dataAsArray);
2008     }
2009     }else{
2010     //alert('unhandled "feed_' + feed + '"');
2011    
2012     }
2013    
2014    
2015    
2016     }
2017    
2018     function decode_base64(s) {
2019     var e={},i,k,v=[],r='',w=String.fromCharCode;
2020     var n=[[65,91],[97,123],[48,58],[43,44],[47,48]];
2021    
2022     for(z in n){for(i=n[z][0];i<n[z][1];i++){v.push(w(i));}}
2023     for(i=0;i<64;i++){e[v[i]]=i;}
2024    
2025     for(i=0;i<s.length;i+=72){
2026     var b=0,c,x,l=0,o=s.substring(i,i+72);
2027     for(x=0;x<o.length;x++){
2028     c=e[o.charAt(x)];b=(b<<6)+c;l+=6;
2029     while(l>=8){r+=w((b>>>(l-=8))%256);}
2030     }
2031     }
2032     return r;
2033     }
2034     function decode_base64toArray(s) {
2035     var e={},i,k,v=[],r=[],w=String.fromCharCode;
2036     var n=[[65,91],[97,123],[48,58],[43,44],[47,48]];
2037    
2038     for(z in n){for(i=n[z][0];i<n[z][1];i++){v.push(w(i));}}
2039     for(i=0;i<64;i++){e[v[i]]=i;}
2040    
2041     for(i=0;i<s.length;i+=72){
2042     var b=0,c,x,l=0,o=s.substring(i,i+72);
2043     for(x=0;x<o.length;x++){
2044     c=e[o.charAt(x)];b=(b<<6)+c;l+=6;
2045     while(l>=8){r.push((b>>>(l-=8))%256);}
2046     }
2047     }
2048     return r;
2049     }
2050    
2051    
2052    
2053     function processExtObj (o){
2054     switch (o[0]){
2055     case "channel_info":
2056     channels[o[1].id] = o[1];
2057     channels.list.push (channels[o[1].id]);
2058     channels[o[1].id].index =channels.length;
2059     channels.length+=1;
2060     return true;
2061     default:
2062     return false;
2063     break;
2064     }
2065     }
2066    
2067     function onError(evt)
2068     {
2069     writeToScreen("ERROR!");
2070     }
2071    
2072     function doSend(message)
2073     {
2074     writeToScreen("SENT: " + message);
2075     websocket.send(message);
2076     }
2077    
2078     function writeToScreen(message)
2079     {
2080     var d = new Date();
2081     //Messages.push(new Message(200,(d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() ) + ":" + message));
2082     output.value = d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ":" + message + "\n" + output.value;
2083     }
2084    
2085     function fillFromTemplate(e){
2086     document.getElementById("text").value = e.value;
2087     }
2088    
2089     isMainScriptLoaded = true;
2090    
2091    
2092     //+ Jonas Raoni Soares Silva
2093     //@ http://jsfromhell.com/geral/utf-8 [rev. #1]
2094    
2095     UTF8 = {
2096     encode: function(s){
2097     for(var c, i = -1, l = (s = s.split("")).length, o = String.fromCharCode; ++i < l;
2098     s[i] = (c = s[i].charCodeAt(0)) >= 127 ? o(0xc0 | (c >>> 6)) + o(0x80 | (c & 0x3f)) : s[i]
2099     );
2100     return s.join("");
2101     },
2102     decode: function(s){
2103     for(var a, b, i = -1, l = (s = s.split("")).length, o = String.fromCharCode, c = "charCodeAt"; ++i < l;
2104     ((a = s[i][c](0)) & 0x80) &&
2105     (s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ?
2106     o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "")
2107     );
2108     return s.join("");
2109     }
2110     };