ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/html5client/main.js
Revision: 1.2
Committed: Sun Nov 4 09:30:25 2012 UTC (11 years, 7 months ago) by sf-demisephi
Content type: application/javascript
Branch: MAIN
Changes since 1.1: +139 -76 lines
Log Message:
Modified map structure

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 sf-demisephi 1.2 map_clear();
773 root 1.1 doSend('setup tileset 1 excmd 1 smoothing 1 mapinfocmd 1 facecache 1 newmapcmd 1 extmap 1 fxix 3 darkness 1 extcmd 2 msg 2 frag 0 map1acmd 1 spellmon 1 itemcmd 2 exp64 1 widget 1 lzf 0 mapsize ' + smapsize);
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 sf-demisephi 1.2 function MapCell(){
953     this.previousCell = null;
954     this.nextCell = null;
955     this.data = {};
956     clear_cell(this.data);
957     }
958    
959     function MapRow(){
960     this.previousRow = null;
961     this.nextRow = null;
962     this.firstCell = null;
963     this.lastCell = null;
964     this.length = 0;
965     while (this.length<mapsize.width){
966     this.addCell(new MapCell());
967     }
968     }
969     MapRow.prototype.addCell = function (cell){
970     if (this.firstCell == null){
971     this.firstCell = this.lastCell = cell;
972    
973     this.lastCell.nextCell = this.firstCell;
974     this.lastCell.previousCell = this.firstCell;
975    
976     this.firstCell.nextCell = this.lastCell;
977     this.firstCell.previousCell = this.lastCell;
978    
979     this.length = 1;
980     return;
981     }
982     this.lastCell.nextCell = cell;
983     cell.previousCell = this.lastCell;
984     this.lastCell = cell;
985     this.firstCell.previousCell = cell;
986     cell.nextCell = this.firstCell;
987     this.length+=1;
988     }
989    
990     MapRow.prototype.shift = function (){
991     var ret = this.firstCell;
992     this.firstCell = ret.nextCell;
993     this.lastCell.nextCell = this.firstCell;
994     this.firstCell.previousCell = this.lastCell;
995     return ret;
996 root 1.1 }
997    
998 sf-demisephi 1.2 MapRow.prototype.pop = function (){
999     var ret = this.lastCell;
1000     this.lastCell = ret.previousCell;
1001     this.lastCell.nextCell = this.firstCell;
1002     this.firstCell.previousCell = this.lastCell;
1003     return ret;
1004     }
1005 root 1.1
1006 sf-demisephi 1.2 MapRow.prototype.push = function (cell){
1007     this.addCell(cell);
1008     }
1009 root 1.1
1010 sf-demisephi 1.2 MapRow.prototype.unshift = function (cell){
1011     var tmp = this.firstCell;
1012     this.firstCell = cell;
1013     this.firstCell.nextCell = tmp;
1014     tmp.previousCell = this.firstCell;
1015     this.firstCell.previousCell = this.lastCell;
1016     this.lastCell.nextCell = this.firstCell;
1017 root 1.1 }
1018    
1019 sf-demisephi 1.2 function map_clear (){
1020     Map = {length:0,firstRow:null,lastRow : null,addRow:function (row){
1021     if (this.firstRow==null){
1022     this.firstRow = this.lastRow = row;
1023     this.length = 1;
1024     return;
1025 root 1.1 }
1026 sf-demisephi 1.2 this.lastRow.nextRow = row;
1027     row.previousRow = this.lastRow;
1028     this.lastRow = row;
1029     row.nextRow = this.firstRow;
1030     this.firstRow.previousRow = row;
1031     this.length++;
1032     }};
1033    
1034     while (Map.length<mapsize.height){
1035     Map.addRow(new MapRow());
1036 root 1.1 }
1037    
1038 sf-demisephi 1.2 if (stage&&stage.stageWidth)
1039     ctx.clearRect(0,0,stage.stageWidth,stage.stageHeight);
1040     }
1041 root 1.1
1042 sf-demisephi 1.2 function map_get_cell (x,y){
1043     var i = 0;
1044     var mapRow = Map.firstRow;
1045     while (i<y){
1046     mapRow = mapRow.nextRow;
1047     ++i;
1048     }
1049     i = 0;
1050     var mapCell = mapRow.firstCell;
1051     while (i<x){
1052     mapCell=mapCell.nextCell;
1053     ++i;
1054     }
1055     return mapCell.data;
1056 root 1.1 }
1057    
1058     function scroll_map (dx,dy){
1059     var x,y;
1060     var tmpDx = dx;
1061     var tmpDy = dy;
1062 sf-demisephi 1.2 var i=0;
1063     while (i<tmpDy){
1064 root 1.1
1065 sf-demisephi 1.2 Map.firstRow = Map.firstRow.nextRow;
1066     Map.addRow(new MapRow());
1067     Map.length -=1;
1068     ++i;
1069     }
1070     i=0;
1071     while (tmpDy<i){
1072     var mapRow = new MapRow();
1073     mapRow.nextRow = Map.firstRow;
1074     Map.firstRow.previousRow = mapRow;
1075     mapRow.previousRow = Map.lastRow;
1076     Map.lastRow.nextRow = mapRow;
1077     Map.firstRow = mapRow;
1078     --i;
1079     }
1080     i = 0;
1081     while (i<tmpDx){
1082     var row = Map.firstRow;
1083     do {
1084     row.shift();
1085     row.push(new MapCell());
1086     row = row.nextRow;
1087     }while (row!=Map.firstRow);
1088     i++;
1089     }
1090     i = 0;
1091     while (tmpDx<i){
1092     var row = Map.firstRow;
1093     do {
1094     row.pop();
1095     row.unshift(new MapCell());
1096     row = row.nextRow;
1097     }while (row!=Map.firstRow);
1098     i--;
1099 root 1.1 }
1100     }
1101    
1102     function feed_map1a (stringData,data){
1103 sf-demisephi 1.2
1104 root 1.1 scroll_map(dx,dy);
1105     dx = dy = 0;
1106    
1107     var x,y;
1108    
1109     var index = 6;
1110 sf-demisephi 1.2
1111     while (index<data.length-2){
1112 root 1.1 var flags = (data[index++]<<8) + data[index++];
1113     x = ((flags >> 10) & 63);
1114     y = ((flags >> 4) & 63);
1115    
1116     cell = map_get_cell (x, y);
1117     if (!(flags&15)){
1118     clear_cell(cell);
1119     //ctx.clearRect(x<<6,(y<<6),64,64);
1120     continue;
1121     }
1122    
1123     if (cell.darkness==0){
1124     cell.darkness = 256;
1125     }
1126    
1127     if ((flags & 8)){
1128     do {
1129     var cmd = 0;
1130     var ext = 0;
1131    
1132     ext = data[index++];
1133     cmd = ext & 0x7f;
1134     if (cmd<4){
1135     cell.darkness = 255 - ext * 64 + 1;
1136     }else if (cmd == 5){
1137     cell.stat_width = 1;
1138     cell.stat_hp = data[index++];
1139     }else if (cmd == 6) {// monster width{
1140     cell.stat_width = data[index++] + 1;
1141     }else if (cmd == 0x47){
1142     if (data[index] == 1) cell.player = data [index + 1];
1143     else if (data[index] == 2) cell.player = data [index + 2] + (data [index + 1] << 8);
1144     else if (data[index] == 3) cell.player = data [index + 3] + (data [index + 2] << 8) + (data [index + 1] << 16);
1145     else if (data[index] == 4) cell.player = data [index + 4] + (data [index + 3] << 8) + (data [index + 2] << 16) + (data [index + 1] << 24);
1146    
1147 sf-demisephi 1.2 index += data[index] +1;
1148 root 1.1 }
1149     else if (cmd == 8) // cell flags
1150     cell.flags = data[index++];
1151     else if (ext & 0x40) // unknown, multibyte => skip
1152     index+= data[index]+1;
1153     else
1154     index++;
1155     }while (ext&0x80);
1156     }
1157    
1158    
1159    
1160     for (var z = 0; z <= 2; ++z)
1161     if ((flags & (4 >> z)))
1162     {
1163     var face = (data [index++] << 8) + data [index++];
1164 sf-demisephi 1.2 //need_facenum (face);
1165 root 1.1 cell.tiles [z] = face;
1166     }
1167 sf-demisephi 1.2 //Map[y][x]=cell;
1168 root 1.1
1169    
1170     }
1171     drawMap();
1172     return true;
1173    
1174     }
1175    
1176     function drawMap(){
1177    
1178 sf-demisephi 1.2
1179 root 1.1 ctx.clearRect(0,0,stage.stageWidth,stage.stageHeight);
1180     ctx.fillStyle = "#000";
1181     ctx.fillRect(0,0,canvas.width,canvas.height);
1182    
1183     for (var i = 0;i<mapsize.height;++i){
1184     for (var j=0;j<mapsize.width;++j){
1185     var x = j<<6;
1186     var y = i<<6;
1187     var cellx = map_get_cell(j,i);
1188     for (var z=0;z<=2;++z){
1189     if (!cellx.tiles[z])
1190     continue;
1191     var img = tilesInfo.getImgByFaceNum(cellx.tiles[z]);
1192     if (img){
1193     ctx.drawImage(img,x,y);
1194     }else{
1195    
1196     }
1197     }
1198     }
1199     }
1200     }
1201    
1202     function feed_ext (data,dataAsArray){
1203    
1204    
1205    
1206    
1207    
1208     if (data.indexOf ("channel_info")>0){
1209     var channel_info = JSON.parse(data.substr(4))[1];
1210     channels_add(channel_info);
1211     return true;
1212     }else{
1213    
1214     var o = JSON.parse(data.substr(4));
1215     var replyID = parseInt(o[0].split("-")[1]);
1216    
1217     if (replyID == 100){
1218     baseURL = o[1];
1219     baseURL = "http://testserver.deliantra.net:13327" + baseURL + "";
1220     doSend('requestinfo skill_info');
1221    
1222     }else if (replyID==101){
1223     expTableFacenum = parseInt(o[1]);
1224     doSend("addme");
1225     }
1226     else{
1227    
1228     }
1229    
1230    
1231     writeToScreen(data);
1232     }
1233     return false;
1234     }
1235     var Constants = {
1236     a_none : 0,
1237     a_readied : 1,
1238     a_wielded : 2,
1239     a_worn : 3,
1240     a_active : 4,
1241     a_applied : 5,
1242     F_APPLIED : 0x000F,
1243     F_LOCATION : 0x00F0,
1244     F_UNPAID : 0x0200,
1245     F_MAGIC : 0x0400,
1246     F_CURSED : 0x0800,
1247     F_DAMNED : 0x1000,
1248     F_OPEN : 0x2000,
1249     F_NOPICK : 0x4000,
1250     F_LOCKED : 0x8000
1251     };
1252     function Buffer (dataArray){
1253     this.buffer = dataArray;
1254     this.position = 0;
1255     this.length = dataArray.length;
1256     return this;
1257     }
1258    
1259     Buffer.prototype.unpack_w = function (){
1260     var num = 0;
1261     var byte = 0;
1262     do {
1263     num*=128;
1264     byte = parseInt(this.buffer[this.position++]);
1265     num+=byte&0x7f;
1266     }while (byte&0x80);
1267     return num;
1268     };
1269    
1270     Buffer.prototype.readUint32 = function (){
1271     var ret = 0;
1272     for (var i=0;i<4;++i){
1273     ret*=256;
1274     ret+=this.buffer[this.position++];
1275     }
1276     return ret;
1277     };
1278    
1279     Buffer.prototype.readUint8 = function (){
1280     var ret = 0;
1281     for (var i=0;i<1;++i){
1282     ret*=256;
1283     ret+=parseInt(this.buffer[this.position++]);
1284     }
1285     return ret;
1286     };
1287    
1288     Buffer.prototype.readUint16 = function (){
1289     var ret = 0;
1290     for (var i=0;i<2;++i){
1291     ret*=256;
1292     ret+=this.buffer[this.position++];
1293     }
1294     return ret;
1295     };
1296    
1297     Buffer.prototype.readString = function (len){
1298     var ret = "";
1299    
1300     if ( typeof (len) != "undefined"){
1301     for (var i=0;i<len;++i){
1302     ret+=String.fromCharCode(this.buffer[this.position++]);
1303     }
1304     }else{
1305    
1306     while (this.buffer[this.position]!=0){
1307     ret+=String.fromCharCode(this.buffer[this.position++]);
1308     }
1309     }
1310    
1311     return ret;
1312     };
1313    
1314    
1315    
1316     function unselectable (target){
1317     target.setAttribute('unselectable','on');
1318     if (typeof target.onselectstart != "undefined") //IE route
1319     target.onselectstart = function() { return false }
1320     else if (typeof target.style.MozUserSelect != "undefined") //Firefox route
1321     target.style.MozUserSelect = "none"
1322     else //All other route (ie: Opera)
1323     target.onmousedown = function() { return false }
1324     }
1325    
1326     function Item (){
1327     this.itemId = 0;
1328     this.flags = 0;
1329     this.weight = 0;
1330     this.face = 0;
1331     this.name = "";
1332     this.namepl = "";
1333     this.animation_id=0;
1334     this.anim_speed=0;
1335     this.nr_of=0;
1336     this.clientType=0;
1337     }
1338    
1339    
1340     function feed_replyinfo (data){
1341     doSend('exti ["resource",'+exti.getNextId()+',"exp_table"]');
1342    
1343     data = data.substr("replyinfo ".length);
1344     var type = data.substr(0,data.indexOf("\n")).trim();
1345     if (type == "skill_info"){
1346     data = data.substr(type.length+1).split("\n");
1347     for (var i=0;i<data.length;++i){
1348     if (data[i].indexOf(":")){
1349     data[i] = (""+data[i]).split(":");
1350     skillNames[parseInt(data[i][0])] = data[i][1];
1351    
1352     }
1353    
1354    
1355     }
1356     }
1357    
1358     }
1359    
1360     function feed_item2 (data,dataAsArray){
1361     var buff = new Buffer(dataAsArray);
1362     buff.position = 6;
1363     var container = buff.readUint32();
1364    
1365     while (buff.position<buff.length){
1366     var item = new Item();
1367    
1368     item.itemId = buff.readUint32();
1369    
1370     item.flags = buff.readUint32();
1371     item.weight = buff.readUint32();
1372     item.face = buff.readUint32();
1373     var len = (buff.readUint8());
1374    
1375     var names = (buff.readString(len)).split(String.fromCharCode(0));
1376     item.name = names[0];
1377     item.namepl = "";
1378    
1379     if (names.length>1)
1380     item.namepl = names[1];
1381    
1382     item.animation_id = buff.readUint16();
1383     item.anim_speed = buff.readUint8();
1384     item.nr_of = buff.readUint32();
1385     item.clientType = buff.readUint16();
1386     if (container!=0){
1387     myItems.push (item);
1388     }else{
1389     floorItems.push(item);
1390     }
1391     }
1392     if (container==0){
1393     xFloorWindow.contents.innerHTML="";
1394     for (var i=0;i<floorItems.length;++i){
1395     var item = floorItems[i];
1396     if (item.itemId==null||isNaN(item.itemId))
1397     continue;
1398     var img = tilesInfo.getImgByFaceNum(item.face);
1399     var div = document.createElement("div");
1400     xFloorWindow.contents.appendChild(div);
1401     if (img){
1402     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>"
1403     }else{
1404     div.innerHTML+="<div><input type='hidden' value='"+item.itemId+"'/>"+(item.nr_of>1?item.namepl:item.name)+"</div>"
1405     }
1406    
1407     div.addEventListener("click",floorInventoryItemClick);
1408     div.addEventListener("mouseover",inventoryItemMouseOver);
1409     div.addEventListener("mouseout",inventoryItemMouseOut);
1410     div.addEventListener("mousemove",inventoryItemMouseMove);
1411    
1412     }
1413    
1414    
1415     }
1416     updateItemsList();
1417     return false;
1418     }
1419    
1420     function Spell (){
1421    
1422     }
1423    
1424     function updateSpellList (){
1425     var content = xPlayerWindow.getElementsByClassName("spellbook_widnow_content")[0];
1426     content.style.display = "block";
1427    
1428     content.innerHTML = "";
1429     var table;
1430     var tr;
1431     var td;
1432    
1433     content.appendChild(table = document.createElement("table"));
1434     table.style.width="100%";
1435     if (mySpells.length<=0){
1436     return;
1437     }
1438     table.appendChild(tr = document.createElement("tr"));
1439     item = mySpells[0];
1440     for (s in item){
1441    
1442     if ((typeof(item[s])==typeof(1))||(typeof(item[s])==typeof(""))){
1443     if (s=="tag"){
1444    
1445     }else if (s=="message"){
1446    
1447     }else if (s=="face"){
1448     tr.appendChild(td=document.createElement("td"));
1449     td.innerHTML = s;
1450     }else{
1451     tr.appendChild(td=document.createElement("td"));
1452     td.innerHTML = s;
1453     }
1454     }
1455    
1456     }
1457    
1458    
1459     mySpells.each(function (item,i,p){
1460    
1461     table.appendChild(tr = document.createElement("tr"));
1462     tr.index = i;
1463     var img = tilesInfo.getImgByFaceNum(item.face);
1464    
1465     var s;
1466     for (s in item){
1467     if (isNaN(item['face'])){
1468     continue;
1469     }
1470    
1471     if ((typeof(item[s])==typeof(1))||(typeof(item[s])==typeof(""))){
1472     if (s=="tag"){
1473     tr.tag = item[s];
1474     }else if (s=="message"){
1475     tr.message = item[s];
1476     }else if (s=="face"){
1477     tr.appendChild(td=document.createElement("td"));
1478     td.innerHTML = "<img src='"+img.src+"' alt='' style='width:32px;'/>";
1479     }else{
1480     tr.appendChild(td=document.createElement("td"));
1481     td.innerHTML = item[s];
1482     }
1483     }
1484    
1485     }
1486     tr.addEventListener("click",mySpellItemClick);
1487     tr.addEventListener("mouseover",SpellItemMouseOver);
1488     tr.addEventListener("mouseout",SpellItemMouseOut);
1489     tr.addEventListener("mousemove",SpellItemMouseMove);
1490    
1491     /*if (img){
1492     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>"
1493     }else{
1494     div.innerHTML="<div><input type='hidden' value='"+item.itemId+"'/>"+(item.nr_of>1?item.namepl:item.name)+"</div>"
1495     }*/
1496    
1497    
1498     },{})
1499    
1500    
1501     }
1502     function updateSkillList (){
1503     var content = xPlayerWindow.getElementsByClassName("skills_widnow_content")[0];
1504    
1505    
1506     content.innerHTML = "";
1507     var tableLeft;
1508     var tableRight;
1509     var tr;
1510     var td;
1511    
1512     content.appendChild(tableLeft = document.createElement("table"));
1513     tableLeft.style.width="45%";
1514     tableLeft.style.float = "left";
1515     content.appendChild(tableRight = document.createElement("table"));
1516     tableRight.style.width="45%";
1517     tableRight.style.float = "right";
1518    
1519     var j=0;
1520    
1521     for (i=CS_STAT_SKILLINFO;i<CS_STAT_SKILLINFO+CS_NUM_SKILLS;++i){
1522    
1523     if (!myStats[i]){
1524     continue;
1525     }
1526     var table = j%2==0 ? tableLeft : tableRight;
1527    
1528     table.appendChild(tr = document.createElement("tr"));
1529     tr.index = i;
1530    
1531    
1532     tr.appendChild(td=document.createElement("td"));
1533     td.innerHTML = skillNames[i];
1534    
1535     for (var k =0 ;k<myStats[i].length;++k){
1536    
1537     tr.appendChild(td=document.createElement("td"));
1538     td.innerHTML = myStats[i][k];
1539    
1540     }
1541     tr.appendChild(td=document.createElement("td"));
1542     td.innerHTML = Math.floor(myStats[i][1]/expTable[parseInt(myStats[i][0])])*100 + "%";
1543     /*tr.addEventListener("click",mySpellItemClick);
1544     tr.addEventListener("mouseover",SpellItemMouseOver);
1545     tr.addEventListener("mouseout",SpellItemMouseOut);
1546     tr.addEventListener("mousemove",SpellItemMouseMove);
1547     */
1548     ++j;
1549     };
1550    
1551    
1552     }
1553    
1554     function mySpellItemClick(e){
1555     if (keys.ctrl){
1556     doSend("command invoke " + mySpells[this.index].name);
1557     }else if (keys.shift){
1558     doSend("command cast " + mySpells[this.index].name);
1559     }
1560     }
1561    
1562    
1563     function SpellItemMouseOver(e){
1564     this.style.background = "solid";
1565     this.style.backgroundColor="white";
1566    
1567     xInfoWindow.contents.innerHTML = this.message + "<small><br/>shift-click to cast<br/>ctrl-click to invoke</small>";
1568     xInfoWindow.show(true);
1569     xInfoWindow.style.left = (e.clientX+5)+"px";
1570     xInfoWindow.style.top = (e.clientY+5)+"px";
1571     }
1572    
1573     function SpellItemMouseMove(e){
1574    
1575     xInfoWindow.style.left = (e.clientX+5)+"px";
1576     xInfoWindow.style.top = (e.clientY+5)+"px";
1577    
1578     }
1579    
1580     function SpellItemMouseOut(e){
1581     this.style.background = "transparent";
1582     xInfoWindow.show(false);
1583     }
1584    
1585    
1586     function feed_addspell (data,dataAsArray){
1587    
1588     var buff = new Buffer(dataAsArray);
1589     buff.position = data.indexOf(" ")+1;
1590     while (buff.position<buff.length){
1591     spell=new Spell();
1592    
1593     spell.tag = buff.readUint32();
1594    
1595     spell.minLevel = buff.readUint16();
1596    
1597     spell.castingTime = buff.readUint16();
1598    
1599     spell.mana = buff.readUint16();
1600    
1601     spell.grace = buff.readUint16();
1602    
1603     spell.level = buff.readUint16();
1604    
1605     spell.skill = buff.readUint8();
1606    
1607     spell.path = buff.readUint32();
1608    
1609     spell.face = buff.readUint32();
1610     var len = buff.readUint8();
1611     spell.name = buff.readString(len);
1612     len = buff.readUint16();
1613     spell.message = buff.readString(len);
1614     mySpells.push(spell);
1615     }
1616    
1617    
1618     }
1619    
1620     function feed_delinv (data,dataAsArray){
1621     var container = parseInt(data.split(" ")[1]);
1622     if (container!=0){
1623     myItems = [];
1624     }else{
1625     floorItems = [];
1626     }
1627     return false;
1628     }
1629    
1630     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];
1631    
1632     function feed_fx (data,dataAsArray){
1633    
1634     var buff = new Buffer(dataAsArray);
1635     buff.position = 3;
1636     var ignore = true;
1637     while (buff.position<buff.length){
1638     var id = buff.unpack_w();
1639     var len = buff.readUint8();
1640     var nameX = "";
1641     for (var i = 0;i<len;++i){
1642     var c = parseInt(buff.readUint8());
1643     var out="";
1644     out+="0123456789abcdef"[c&0xf];
1645     out= "0123456789abcdef"[c>>4]+out;
1646     nameX+=out;
1647     }
1648     var img = document.createElement("img");
1649    
1650     var e;
1651     if (tilesInfo.getImgByFaceNum(id)){
1652    
1653     }else{
1654     if (nameX.length>3){
1655     if (nameX=="f66e1bc0a5662e59be0253a84ee06c"){
1656     var req = new XMLHttpRequest();
1657     req.open('GET', baseURL+""+nameX, false);
1658     req.send(null);
1659     if(req.status == 200)
1660     messageBox(req.responseText);
1661     /*
1662     var iframe = $_("iframe");
1663     appendToBody(iframe);
1664     iframe.style.display = "none";
1665     iframe.onload = function (){
1666     var doc = null;
1667     try{
1668     doc = iframe.document || iframe.contentDocument || iframe.contentWindow && iframe.contentWindow.document || null;
1669     } catch(err) {
1670     messageBox('error: ' + err.description);
1671     }
1672     messageBox (doc.body.innerHTML);
1673     }
1674     iframe.src =baseURL+""+nameX;*/
1675    
1676    
1677     }else{
1678     tilesInfo.listLoading.push (e={name:nameX,id:id,img:img,src:baseURL+""+nameX});
1679     e.img.parent = e;
1680     e.img.onload = function (){tilesInfo.markAsLoaded(this.parent);}
1681     if (!tilesInfo.isLoading){
1682    
1683     tilesInfo.isLoading = true;
1684     e.img.src = e.src;
1685     //alert("loading: " + e.src);
1686     }
1687     }
1688     }else{
1689     //alert ("face num " + id + " has name len :" + len + " !!!!");
1690     //prompt("",dataAsArray);
1691     }
1692     }
1693     }
1694    
1695     return false;
1696     }
1697    
1698    
1699     function feed_newmap (data,dataAsArray){
1700     //messageBox("newmap");
1701     map_clear();
1702 sf-demisephi 1.2
1703 root 1.1 }
1704    
1705     function feed_mapinfo (data,dataAsArray){
1706     var parts = data.split(/ /);
1707     //map_clear();
1708     return false;
1709     }
1710    
1711    
1712     function feed_msg (data,dataAsArray){
1713     var o = null;
1714     if (data.indexOf("[")>0){
1715     o = JSON.parse(data.substr(4));
1716    
1717     channels_addMessage(o[1],o)
1718     return true;
1719     }
1720     return false;
1721     }
1722    
1723    
1724     function feed_anim (data,dataAsArray){
1725     return false;
1726     }
1727    
1728     /*
1729     CONSTANTS
1730     */
1731    
1732     var TICK = 0.120,
1733     CS_QUERY_YESNO = 0x1,
1734     CS_QUERY_SINGLECHAR = 0x2,
1735     CS_QUERY_HIDEINPUT = 0x4,
1736     CS_SAY_NORMAL = 0x1,
1737     CS_SAY_SHOUT = 0x2,
1738     CS_SAY_GSAY = 0x4,
1739     FLOAT_MULTI = 100000,
1740     FLOAT_MULTF = 100000.0,
1741     CS_STAT_HP = 1,
1742     CS_STAT_MAXHP = 2,
1743     CS_STAT_SP = 3,
1744     CS_STAT_MAXSP = 4,
1745     CS_STAT_STR = 5,
1746     CS_STAT_INT = 6,
1747     CS_STAT_WIS = 7,
1748     CS_STAT_DEX = 8,
1749     CS_STAT_CON = 9,
1750     CS_STAT_CHA = 10,
1751     CS_STAT_EXP = 11,
1752     CS_STAT_LEVEL = 12,
1753     CS_STAT_WC = 13,
1754     CS_STAT_AC = 14,
1755     CS_STAT_DAM = 15,
1756     CS_STAT_ARMOUR = 16,
1757     CS_STAT_SPEED = 17,
1758     CS_STAT_FOOD = 18,
1759     CS_STAT_WEAP_SP = 19,
1760     CS_STAT_RANGE = 20,
1761     CS_STAT_TITLE = 21,
1762     CS_STAT_POW = 22,
1763     CS_STAT_GRACE = 23,
1764     CS_STAT_MAXGRACE = 24,
1765     CS_STAT_FLAGS = 25,
1766     CS_STAT_WEIGHT_LIM = 26,
1767     CS_STAT_EXP64 = 28,
1768     CS_STAT_SPELL_ATTUNE = 29,
1769     CS_STAT_SPELL_REPEL = 30,
1770     CS_STAT_SPELL_DENY = 31,
1771     CS_STAT_RESIST_START = 100,
1772     CS_STAT_RESIST_END = 117,
1773     CS_STAT_RES_PHYS = 100,
1774     CS_STAT_RES_MAG = 101,
1775     CS_STAT_RES_FIRE = 102,
1776     CS_STAT_RES_ELEC = 103,
1777     CS_STAT_RES_COLD = 104,
1778     CS_STAT_RES_CONF = 105,
1779     CS_STAT_RES_ACID = 106,
1780     CS_STAT_RES_DRAIN = 107,
1781     CS_STAT_RES_GHOSTHIT = 108,
1782     CS_STAT_RES_POISON = 109,
1783     CS_STAT_RES_SLOW = 110,
1784     CS_STAT_RES_PARA = 111,
1785     CS_STAT_TURN_UNDEAD = 112,
1786     CS_STAT_RES_FEAR = 113,
1787     CS_STAT_RES_DEPLETE = 114,
1788     CS_STAT_RES_DEATH = 115,
1789     CS_STAT_RES_HOLYWORD = 116,
1790     CS_STAT_RES_BLIND = 117,
1791     CS_STAT_SKILLINFO = 140,
1792     CS_NUM_SKILLS = 50,
1793     SF_FIREON = 0x01,
1794     SF_RUNON = 0x02,
1795     NDI_BLACK = 0,
1796     NDI_WHITE = 1,
1797     NDI_NAVY = 2,
1798     NDI_RED = 3,
1799     NDI_ORANGE = 4,
1800     NDI_BLUE = 5,
1801     NDI_DK_ORANGE = 6,
1802     NDI_GREEN = 7,
1803     NDI_LT_GREEN = 8,
1804     NDI_GREY = 9,
1805     NDI_BROWN = 10,
1806     NDI_GOLD = 11,
1807     NDI_TAN = 12,
1808     NDI_MAX_COLOR = 12,
1809     NDI_COLOR_MASK = 0x1f,
1810     NDI_REPLY = 0x20,
1811     NDI_NOCRATE = 0x40,
1812     NDI_CLEAR = 0x80,
1813     a_none = 0,
1814     a_readied = 1,
1815     a_wielded = 2,
1816     a_worn = 3,
1817     a_active = 4,
1818     a_applied = 5,
1819     F_APPLIED = 0x000F,
1820     F_LOCATION = 0x00F0,
1821     F_UNPAID = 0x0200,
1822     F_MAGIC = 0x0400,
1823     F_CURSED = 0x0800,
1824     F_DAMNED = 0x1000,
1825     F_OPEN = 0x2000,
1826     F_NOPICK = 0x4000,
1827     F_LOCKED = 0x8000,
1828     CF_FACE_NONE = 0,
1829     CF_FACE_BITMAP = 1,
1830     CF_FACE_XPM = 2,
1831     CF_FACE_PNG = 3,
1832     CF_FACE_CACHE = 0x10,
1833     FACE_FLOOR = 0x80,
1834     FACE_COLOR_MASK = 0xf,
1835     UPD_LOCATION = 0x01,
1836     UPD_FLAGS = 0x02,
1837     UPD_WEIGHT = 0x04,
1838     UPD_FACE = 0x08,
1839     UPD_NAME = 0x10,
1840     UPD_ANIM = 0x20,
1841     UPD_ANIMSPEED = 0x40,
1842     UPD_NROF = 0x80,
1843     UPD_SP_MANA = 0x01,
1844     UPD_SP_GRACE = 0x02,
1845     UPD_SP_LEVEL = 0x04,
1846     SOUND_NORMAL = 0,
1847     SOUND_SPELL = 1,
1848    
1849     PICKUP_NOTHING = 0x00000000,
1850    
1851     PICKUP_DEBUG = 0x10000000,
1852     PICKUP_INHIBIT = 0x20000000,
1853     PICKUP_STOP = 0x40000000,
1854     PICKUP_NEWMODE = 0x80000000,
1855    
1856     PICKUP_RATIO = 0x0000000F,
1857    
1858     PICKUP_FOOD = 0x00000010,
1859     PICKUP_DRINK = 0x00000020,
1860     PICKUP_VALUABLES = 0x00000040,
1861     PICKUP_BOW = 0x00000080,
1862    
1863     PICKUP_ARROW = 0x00000100,
1864     PICKUP_HELMET = 0x00000200,
1865     PICKUP_SHIELD = 0x00000400,
1866     PICKUP_ARMOUR = 0x00000800,
1867    
1868     PICKUP_BOOTS = 0x00001000,
1869     PICKUP_GLOVES = 0x00002000,
1870     PICKUP_CLOAK = 0x00004000,
1871     PICKUP_KEY = 0x00008000,
1872    
1873     PICKUP_MISSILEWEAPON = 0x00010000,
1874     PICKUP_ALLWEAPON = 0x00020000,
1875     PICKUP_MAGICAL = 0x00040000,
1876     PICKUP_POTION = 0x00080000,
1877    
1878     PICKUP_SPELLBOOK = 0x00100000,
1879     PICKUP_SKILLSCROLL = 0x00200000,
1880     PICKUP_READABLES = 0x00400000,
1881     PICKUP_MAGIC_DEVICE = 0x00800000,
1882    
1883     PICKUP_NOT_CURSED = 0x01000000,
1884    
1885     PICKUP_JEWELS = 0x02000000,
1886     PICKUP_FLESH = 0x04000000;
1887    
1888     var stat_32bit = [CS_STAT_WEIGHT_LIM,CS_STAT_SPELL_ATTUNE,CS_STAT_SPELL_REPEL,CS_STAT_SPELL_DENY,CS_STAT_EXP];
1889    
1890    
1891     function feed_stats (data,dataAsArray){
1892     var buff = new Buffer(dataAsArray);
1893     buff.position = "stats".length + 1;
1894     while (buff.position < buff.length){
1895     var stat = buff.readUint8();
1896     var value;
1897     if (stat_32bit.contains(stat)){
1898     value = buff.readUint32();
1899     }else if (stat == CS_STAT_SPEED||stat==CS_STAT_WEAP_SP){
1900     value = (1/FLOAT_MULTF) * buff.readUint32();
1901     }else if (stat==CS_STAT_RANGE||stat==CS_STAT_TITLE){
1902     var len = buff.readUint8();
1903     value = buff.readString(len);
1904     }else if (stat == CS_STAT_EXP64){
1905     var hi = buff.readUint32();
1906     var lo = buff.readUint32();
1907     value = hi * Math.pow(2,32) + lo;
1908     }else if (stat>=CS_STAT_SKILLINFO && stat < CS_STAT_SKILLINFO + CS_NUM_SKILLS){
1909     var lvl = buff.readUint8();
1910     var hi = buff.readUint32();
1911     var lo = buff.readUint32();
1912     value = [lvl,hi * Math.pow(2,32) + lo];
1913     }else{
1914     value = buff.readUint16();
1915     }
1916     myStats [stat] = value;
1917     //stats_update (stat);
1918     }
1919    
1920     return true;
1921     }
1922    
1923     function feed_player (data,dataAsArray){
1924     return false;
1925     }
1926    
1927     function feed_drawinfo (data,dataAsArray){
1928     return false;
1929     }
1930    
1931    
1932    
1933     var tilesInfo = {
1934     listLoading:[],
1935     listLoaded:[],
1936    
1937     isLoading: false,
1938     getImgByFaceNum:function (id){
1939     for (var i=0;i<this.listLoaded.length;++i){
1940     if (this.listLoaded[i].id==id){
1941     return this.listLoaded[i].img;
1942     }
1943     }
1944     return null;
1945     },
1946     isImgLoading : function (id){
1947     for (var i=0;i<this.listLoading.length;++i){
1948     if (this.listLoading[i].id==id){
1949     return true;
1950     }
1951     }
1952     return false;
1953     },
1954     markAsLoaded : function (e){
1955     var i;
1956     for (i=0;i<this.listLoading.length;++i){
1957     if (this.listLoading[i].id == e.id){
1958     this.listLoading.splice(i,1);
1959     break;
1960     }
1961     }
1962    
1963     this.listLoaded.push (e);
1964     this.isLoading = false;
1965     while ((this.listLoading.length>0)&&(this.isLoading==false)){
1966    
1967     var e2 = this.listLoading.pop();
1968     if (e2.src.length > baseURL.length + 1){
1969     this.isLoading = true;
1970     e2.img.src = e2.src;
1971     //alert("loading " + e2.src);
1972     e2.onload = e.onload;
1973     }
1974     }
1975     }
1976     }
1977    
1978     var baseURL = "";
1979     DrawLater = {
1980     list : []
1981     };
1982    
1983    
1984     function imgFromString (s){
1985     var img = $_('img');
1986     img.src = s;
1987     return img;
1988     }
1989    
1990     function need_facenum (num){
1991     var img;
1992    
1993     if (tilesInfo.getImgByFaceNum(num)!=null){
1994     return;
1995     }
1996    
1997     /*if ( img = localStorage.getItem("face_" + num)){
1998    
1999     tilesInfo.listLoaded.push({num:num,data: {img:imgFromString(img)}});
2000     return;
2001     }*/
2002     }
2003     var dx = 0;
2004     var dy = 0;
2005    
2006     function feed_map_scroll (data,dataAsArray,base64data){
2007    
2008     data = data.split(/ /);
2009     data.shift();
2010     dx += parseInt(data.shift());
2011     dy += parseInt(data.shift());
2012    
2013    
2014     }
2015    
2016    
2017     function feed_ix (data,dataAsArray,base64data){
2018    
2019     }
2020    
2021     function arr2bytes(arr){
2022     var s = "";
2023     for (var i=0;i<arr.length;++i){
2024     s+=String.fromCharCode(arr[i]);
2025     }
2026     return s;
2027     }
2028     function bytes2arr(s){
2029     var arr = [];
2030     for (var i=0;i<s.length;++i){
2031     arr.push(s.charCodeAt(i));
2032     }
2033     return arr;
2034     }
2035     function $_(p){
2036     if (document.getElementById(p)!=null){
2037     return document.getElementById(p);
2038     }else{
2039     return document.createElement(p);
2040     }
2041     }
2042     var tiles = [];
2043    
2044     function onMessage(evt)
2045     {
2046    
2047     //var data = Widnow.atob(evt.data);
2048     var data = evt.data;
2049     data = (atob(data));
2050    
2051    
2052     //writeToScreen(data);
2053    
2054     var dataAsArray = null;
2055     var patt=/[0-9a-z_]*[^0-9a-z_]/i;
2056     var feed = ""+data.match(patt);
2057     feed=feed.substr(0,feed.length -1);
2058     if (feed=="nul"){
2059     if (data=="newmap"){
2060     feed="newmap";
2061     }else{
2062     return;
2063     }
2064     }
2065     if ((window['feed_' + feed])&&(typeof(window['feed_' + feed])=="function")){
2066     // var retVal = window['feed_' + feed](data,dataAsArray=bytes2arr(evt.data),evt.data);
2067     var retVal = window['feed_' + feed](data,dataAsArray=decode_base64toArray(evt.data),evt.data);
2068     if (!retVal){
2069     //writeToScreen("[" + feed + "] " + data );
2070     //writeToScreen(dataAsArray);
2071     }
2072     }else{
2073     //alert('unhandled "feed_' + feed + '"');
2074    
2075     }
2076    
2077    
2078    
2079     }
2080    
2081     function decode_base64(s) {
2082     var e={},i,k,v=[],r='',w=String.fromCharCode;
2083     var n=[[65,91],[97,123],[48,58],[43,44],[47,48]];
2084    
2085     for(z in n){for(i=n[z][0];i<n[z][1];i++){v.push(w(i));}}
2086     for(i=0;i<64;i++){e[v[i]]=i;}
2087    
2088     for(i=0;i<s.length;i+=72){
2089     var b=0,c,x,l=0,o=s.substring(i,i+72);
2090     for(x=0;x<o.length;x++){
2091     c=e[o.charAt(x)];b=(b<<6)+c;l+=6;
2092     while(l>=8){r+=w((b>>>(l-=8))%256);}
2093     }
2094     }
2095     return r;
2096     }
2097     function decode_base64toArray(s) {
2098     var e={},i,k,v=[],r=[],w=String.fromCharCode;
2099     var n=[[65,91],[97,123],[48,58],[43,44],[47,48]];
2100    
2101     for(z in n){for(i=n[z][0];i<n[z][1];i++){v.push(w(i));}}
2102     for(i=0;i<64;i++){e[v[i]]=i;}
2103    
2104     for(i=0;i<s.length;i+=72){
2105     var b=0,c,x,l=0,o=s.substring(i,i+72);
2106     for(x=0;x<o.length;x++){
2107     c=e[o.charAt(x)];b=(b<<6)+c;l+=6;
2108     while(l>=8){r.push((b>>>(l-=8))%256);}
2109     }
2110     }
2111     return r;
2112     }
2113    
2114    
2115    
2116     function processExtObj (o){
2117     switch (o[0]){
2118     case "channel_info":
2119     channels[o[1].id] = o[1];
2120     channels.list.push (channels[o[1].id]);
2121     channels[o[1].id].index =channels.length;
2122     channels.length+=1;
2123     return true;
2124     default:
2125     return false;
2126     break;
2127     }
2128     }
2129    
2130     function onError(evt)
2131     {
2132     writeToScreen("ERROR!");
2133     }
2134    
2135     function doSend(message)
2136     {
2137     writeToScreen("SENT: " + message);
2138     websocket.send(message);
2139     }
2140    
2141     function writeToScreen(message)
2142     {
2143     var d = new Date();
2144     //Messages.push(new Message(200,(d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() ) + ":" + message));
2145     output.value = d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ":" + message + "\n" + output.value;
2146     }
2147    
2148     function fillFromTemplate(e){
2149     document.getElementById("text").value = e.value;
2150     }
2151    
2152     isMainScriptLoaded = true;
2153    
2154    
2155     //+ Jonas Raoni Soares Silva
2156     //@ http://jsfromhell.com/geral/utf-8 [rev. #1]
2157    
2158     UTF8 = {
2159     encode: function(s){
2160     for(var c, i = -1, l = (s = s.split("")).length, o = String.fromCharCode; ++i < l;
2161     s[i] = (c = s[i].charCodeAt(0)) >= 127 ? o(0xc0 | (c >>> 6)) + o(0x80 | (c & 0x3f)) : s[i]
2162     );
2163     return s.join("");
2164     },
2165     decode: function(s){
2166     for(var a, b, i = -1, l = (s = s.split("")).length, o = String.fromCharCode, c = "charCodeAt"; ++i < l;
2167     ((a = s[i][c](0)) & 0x80) &&
2168     (s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ?
2169     o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "")
2170     );
2171     return s.join("");
2172     }
2173     };