ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/html5client/main.js
Revision: 1.16
Committed: Wed Nov 7 21:15:28 2012 UTC (11 years, 7 months ago) by sf-demisephi
Content type: application/javascript
Branch: MAIN
Changes since 1.15: +109 -7 lines
Log Message:
fixed request for command help added command line

File Contents

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