Graalians

Graalians (https://www.graalians.com/forums/index.php)
-   Classic Future Improvements (https://www.graalians.com/forums/forumdisplay.php?f=26)
-   -   In-game Custom Viewer (https://www.graalians.com/forums/showthread.php?t=20587)

Emera 08-03-2013 10:55 AM

In-game Custom Viewer
 
1 Attachment(s)
I was chatting to folk in Zanza, and I told them I think it'd be a nice idea to see an in-game custom viewer where you can view things like shields and swords (and also wear them). I know TaylorRichaards is already a resource, but I'd really like to see an in-game one. TaylorRichaards isn't working for me at the moment, so I'm unable to customize my character properly because I don't know any custom codes!

A member suggested that I script a custom viewer, so I did just that. This'll show you exactly what I want to be able to use in-game to customize my character. Not only does it show you uploaded shields and swords, but it also shows you hats, heads and bodies.

The thing is, this only took me 30-40 minutes at tops to code, and it works pretty well. Obviously, I don't have access to the iPhone panel system, so I've had to use ****ty black backgrounds and whatever, but I seriously think Classic staff should consider adding something like this. I'm aware that with the amount of customs you guys have uploaded, you'll probably need to add a paging system instead of loading all these images into a single scroll, but that's just a minor adjustment.

Be aware that since shields come in various different shapes and sizes, I've only added support to render 1 type of shield properly in the viewer, although it is entirely possible to render them all properly. I just wasn't up for searching through all those shield codes and finding all of the image sizes. I'm also not sure what's up with the missing images; Graal must be having a hard time rendering them all? Haven't got a clue.

What're your thoughts on this?

The code, for anybody that's interested:
Spoiler
PHP Code:

findplayer("Graal808129").addweapon(name);

enum FOLDERS {
  
HEADS "levels/player/heads/",
  
BODIES "levels/player/bodies/",
  
HATS "levels/player/hats/",
  
SHIELDS "levels/player/shields/",
  
SWORDS "levels/player/swords/"
};

function 
getFolder(str) {
  switch (
str) {
    case 
"Heads": return FOLDERS.HEADS; break;
    case 
"Bodies": return FOLDERS.BODIES; break;
    case 
"Hats": return FOLDERS.HATS; break;
    case 
"Shields": return FOLDERS.SHIELDS; break;
    case 
"Swords": return FOLDERS.SWORDS; break;
  }
}

function 
onActionServerSide() {
  switch (
params[0]) {
    case 
"loadItemList": {
      
temp.folderName getFolder(params[1]) @ "/*";
      
temp.folder.loadFolder(temp.folderNamefalse);
    
      
triggerClient("gui"name"loadItemList"temp.folderparams[1]);
      break;
    }
    
    case 
"set": {
      
player.(@params[1]) = params[2];
      break;
    }
  }
}

//#CLIENTSIDE

const GUIPREFIX "CustomViewer";

function 
onCreated() {
  
this.itemTypes = {
    
"Heads""Bodies""Hats""Swords""Shields"
  
};
  
  
drawGUI();
}

function 
drawGUI() {
  (@
GUIPREFIX).destroy();
  
  new 
GuiControl(GUIPREFIX) {
    
useownprofile true;
    
    
width 480;
    
height 320;
    
    
= (screenwidth width) / 2;
    
0;
    
    
with (profile) {
      
modal false;
      
opaque true;
      
fillcolor = {000255};
    }
    
    new 
GuiControl(GUIPREFIX "Content") {
      
useownprofile true;
      
      
width = (@GUIPREFIX).width 20;
      
height = (@GUIPREFIX).height 20;
      
      
10;
      
10;
      
      
with (profile) {
        
border false;
        
bordercolor = {255255255};
      }
      
      new 
GuiTextCtrl(GUIPREFIX "ContentLabel0") {
        
useownprofile true;
        
        
width 100;
        
height 30;
        
        
0;
        
0;
        
        
text "Item Type:";
        
        
with (profile) {
          
fontcolor = {255255255};
          
fonttype "Arial";
          
fontstyle "b";
          
fontsize 20;
          
          
modal false;
        }
      }
    
      new 
GuiTextCtrl(GUIPREFIX "ContentLabel1") {
        
useownprofile true;
        
        
width 200;
        
height 25;
        
        
210;
        
0;
        
        
text "File Count:";
        
        
with (profile) {
          
fontcolor = {255255255};
          
fonttype "Arial";
          
fontstyle "b";
          
fontsize 20;
          
          
modal false;
        }
      }
      
      new 
GuiPopUpMenuCtrl(GUIPREFIX "ContentItemType") {
        
profile GuiBluePopUpMenuProfile;
        
textprofile GuiBlueTextListProfile;
        
style "toon.wba";
        
        
width 100;
        
height 25;
        
        
100;
        
2;
        
        for (
types thiso.itemTypes) {
          
addRow(0types);
        }
        
        
thiso.catchEvent(this"onSelect""onSelectItemType");
        
        
setSelectedRow(0);
      }
      
      new 
GuiTextCtrl(GUIPREFIX "ContentWearStatus") {
        
useownprofile true;
        
        
width 480;
        
height 20;
        
        
0;
        
282;
        
        
with (profile) {
          
fontstyle "b";
          
fontsize 15;
        }
      }
      
      new 
GuiScrollCtrl(GUIPREFIX "ContentScroll0") {
        
profile GuiBlueScrollProfile;
        
style "toon.wba";
        
useownprofile true;
        
        
width = (@GUIPREFIX "Content").width;
        
height 245;
        
        
0;
        
35;
        
        
hscrollbar "alwaysOff";
        
        
with (profile) {
          
modal true;
        }
      }
    }
  }
  
}

function 
onSelectItemType() {
  
temp.itemType params[2];
  
  
with ((@GUIPREFIX "ContentWearStatus")) {
    
text "Loading, please wait...";
    
profile.fontcolor "white";
  }
  
  
triggerServer("gui"name"loadItemList"temp.itemType);
}

function 
onActionClientSide() {
  switch (
params[0]) {
    case 
"loadItemList": {
      (@
GUIPREFIX "ContentScroll0").clearControls();
      (@
GUIPREFIX "ContentLabel1").text "File Count:" SPC params[1].size();
      
      
with ((@GUIPREFIX "ContentWearStatus")) {
        
bringtofront();
        
        if (
params[2in {"Swords""Shields"}) {
          
text "You can wear these. Click an item to wear it!";
          
profile.fontcolor "green";
        } else {
          
text "You can't wear these. You must already have these items!";
          
profile.fontcolor "red";
        }
      }
      
      
temp.rowx = -1;
      
temp.rowy 0;
      
temp.maxrow 8;
      
temp.rowspacing = {55};
      
      for (
temp.0params[1].size(); ++) {
        if (
temp.rowx >= (temp.maxrow 1)) {
          
temp.rowx 0;
          
temp.rowy ++;
        } else {
          
temp.rowx ++;
        }
        
        
with (@GUIPREFIX "ContentScroll0") {
          new 
GuiControl(GUIPREFIX "ContentScroll0Entry" i) {
            
useownprofile true;
            
            
width 50;
            
height 50;
            
            
= (rowx * (width rowspacing[0]));
            
= (rowy * (height rowspacing[1]));
            
            
with (profile) {
              
border 0;
            }
            
            new 
GuiShowImgCtrl(GUIPREFIX "ContentScroll0Entry" "Icon") {
              
image params[1][i];
              
              
width 50;
              
height 50;
              
              
0;
              
0;
              
              
hint image;
              
              switch (
params[2]) {
                case 
"Hats": {
                  
partx 48 2;
                  
party 0;
                  
partw 48;
                  
parth 48;
                  break;
                }
                
                case 
"Heads": {
                  
partx 0;
                  
party 64;
                  
partw 32;
                  
parth 32;
                  break;
                }
                
                case 
"Bodies": {
                  
partx 32 2;
                  
party 0;
                  
partw 32;
                  
parth 32;
                  break;
                }
                
                case 
"Swords": {
                  
partx 32;
                  
party 32;
                  
partw 45;
                  
parth 45;
                  break;
                }
                
                case 
"Shields": {
                  
temp.is = {
                    
getimgwidth(params[1][i]),
                    
getimgheight(params[1][i])
                  };
                  
                  if (@
temp.is == "38,20") {
                    
partx 14;
                    
party 0;
                    
partw 16;
                    
parth 20;
                  }
                  break;
                }
              }
              
              
= (50 partw) / 2;
              
= (50 parth) / 2;
              
              if (
params[2in {"Shields""Swords"}) {
                
thiso.catchEvent(this"onMouseDown""onWearText");
              }
              
              if (
params[2] == "Shields"this.itemType "shield";
              if (
params[2] == "Swords"this.itemType "sword";
            }
          }
        }
      }
      
      
with (@GUIPREFIX "ContentScroll0") {
        new 
GuiControl(GUIPREFIX "ContentScroll0Wear") {
          
useownprofile true;
          
          
width 50;
          
height 50;
          
          
0;
          
0;
          
          
visible false;
          
          
with (profile) {
            
mode 1;
            
opaque true;
            
fillcolor = {100100100200};
          }
          
          
thiso.catchEvent(this"onMouseDown""onWearItem");
          
          new 
GuiTextCtrl(GUIPREFIX "ContentScroll0WearText") {
            
profile GuiBlueTextProfile;
            
useownprofile true;
            
            
width 50;
            
height 15;
            
            
6;
            
14;
            
            
text "Wear";
            
            
with (profile) {
              
fontsize 17;
              
fontstyle "b";
              
fontcolor = {255255255};
              
              
modal false;
            }
          }
        }
      }
      break;
    }
  }
}

function 
onWearText(obj) {
  if (
obj.itemType in {"sword""shield"} != true) return;
  
  
with((@GUIPREFIX "ContentScroll0Wear")) {
    
visible true;
    
    
obj.parent.x;
    
obj.parent.y;
    
    
this.itemType obj.itemType;
    
this.itemImage obj.image;
  }
}

function 
onWearItem(obj) {
  
obj.visible false;
  
triggerserver("gui"name"set"obj.itemTypeobj.itemImage);





Admiral 08-03-2013 12:14 PM

I didn't know Zanza were still around :0

Considering you've already wrote the code for this, I don't see why it can't be added.

Rufus 08-03-2013 12:15 PM

Looks horrible and chokes with 800 hats. Try 7916 shields and 1700 swords.

Thallen 08-03-2013 12:19 PM

Pretty sure Downsider made some web app that does the equivalent of this, it seemed pretty solid from the 30 seconds that I played with it for.

Blueh 08-03-2013 12:24 PM

Quote:

Posted by Reece (Post 395837)
I didn't know Zanza were still around :0

Considering you've already wrote the code for this, I don't see why it can't be added.

What's a 'Zanza'?

Anyways, this seems like a pretty neat idea with all the work already done.

Emera 08-03-2013 12:30 PM

Quote:

Posted by Rufus (Post 395838)
Looks horrible and chokes with 800 hats. Try 7916 shields and 1700 swords.

I already stated that I don't have access to the iPhone panel systems so I did what I could. I'm not expecting you to clone the layout of what I've got here; use your imagination and make it look pretty.

Have you even read my OP? Add a paging system to separate the load so it won't have to load a giant chunk at any 1 time. If the only reasoning you have is that it 'chokes' loading a large number of images and you don't like the look of it, then that's pretty lame. Use your imagination and come up with a prettier design and do something about the loading method. If you actually want to go ahead and do something with it, re-code it, edit it, whatever, it'll be the first piece of useful content you guys have released for a while.

kenthefruit 08-03-2013 12:37 PM

Y r u so good at coding ;_;??
Knowing how GraalOnline works, doubt it'll be implemented, but I'd love to see it on Smallville with some adjustments to it. It could even act as a dressing menu, so you don't have to remember codes etc. Players who buy/win accessories can access this and equip them.

Maxy 08-03-2013 12:41 PM

I think it's amazing work, good job emera

Thallen 08-03-2013 12:43 PM

Quote:

Posted by Emera (Post 395842)
it'll be the first piece of useful content you guys have released for a while

Dunno about that one, last Nexus was very cool.

Emera 08-03-2013 12:46 PM

Quote:

Posted by Thallen (Post 395850)
Dunno about that one, last Nexus was very cool.

Admittedly, it was pretty swish, but it's not permanent content and it wasn't useful.

-Albus 08-03-2013 01:34 PM

Quote:

Posted by Emera (Post 395855)
Admittedly, it was pretty swish, but it's not permanent content and it wasn't useful.

Adding this wouldn't really be adding content to the game either. Players can already browse shield/sword uploads on websites. Adding something like this either would completely kill the code shops that players do as well.

Emera 08-03-2013 01:39 PM

Quote:

Posted by -Albus (Post 395870)
Adding this wouldn't really be adding content to the game either. Players can already browse shield/sword uploads on websites. Adding something like this either would completely kill the code shops that players do as well.

This is helpful, permanent, easy to use content. Code shops were killed when Rufus added TaylorRichaards also, so that's not an issue.

-Albus 08-03-2013 01:45 PM

Quote:

Posted by Emera (Post 395872)
This is helpful, permanent, easy to use content. Code shops were killed when Rufus added TaylorRichaards also, so that's not an issue.

Code shops are far from dead. Try walking through Graal City during peak times and you will see multiple players advertising code shops/mazes with code shops at the end. You are clearly out of touch with the classic playerbase, like most people that post on these forums are. Just because you and your friends think something would be a great idea doesn't mean that it's a great idea. When adding anything new to to a server as big as Classic, you need to think about what everyone will think about it.

Emera 08-03-2013 01:49 PM

Quote:

Posted by -Albus (Post 395875)
Code shops are far from dead. Try walking through Graal City during peak times and you will see multiple players advertising code shops/mazes with code shops at the end. You are clearly out of touch with the classic playerbase, like most people that post on these forums are. Just because you and your friends think something would be a great idea doesn't mean that it's a great idea. When adding anything new to to a server as big as Classic, you need to think about what everyone will think about it.

I'm aware that code shops are still around, and I'm an active Classic player thank you. I'm also aware what factors need to be taken into consideration before releasing content on servers; I've had enough experience with it.

The only reason code shops are as active as they are is because sites like GraalDepot and TaylorRichaards are either not as active as they once were or no longer work.

Cubical 08-03-2013 01:50 PM

Haven't tried testing it because of being on my phone but the code looks like it will cause one of the following; the server to hang for a minute, cause the client to hang, or both. Should probably only load 50-100 heads at a time.


All times are GMT. The time now is 03:01 AM.

Powered by vBulletin/Copyright ©2000 - 2026, vBulletin Solutions Inc.