ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/html5client/main.js
Revision: 1.3
Committed: Sun Nov 4 16:53:24 2012 UTC (11 years, 7 months ago) by sf-demisephi
Content type: application/javascript
Branch: MAIN
Changes since 1.2: +507 -193 lines
Log Message:
added key repetiion block, implemented run

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