Summoning NPC's from a menu

DJGameFreakTheIguana

Active member
One script I've not been able to get much done with for years. I asked this for Beast Mode where it was suggest I long into the D&D mod, wise of Warduke, I did but couldn't make anything out and never got back to it. I decided to look back into last night where I ended up finding the entities I needed to find.

As far as I can tell, it's a few scripts working all at once, and the menu itself is actually using an image. As best I can, I'm going to list the scripts at work, and anyone who can take a look at it can see if they know how to change it for what I need, which is just summoning 2 or more NPC's of my choice.

First, I was told of this character, Strongheart, who summons's NPC with "@cmd SHSummon -100 10 1". I found he uses this script:

Code:
void SHSummon(float fX, float fY, float fZ)
{//Strongheart's special summon NPC script based on selected NPC
 //fX: X location adjustment
 //fY: Y location adjustment
 //fZ: Z location adjustment

    void self = getlocalvar("self"); //Get calling entity
    int PIndex = getentityproperty(self,"playerindex");
    int MagicS = getglobalvar(PIndex+"1");
    void vSpawn;

    if(MagicS=="Elkhorn"){
      summon("Elkhorn", fX, fY, fZ, "Elkhorn");
    } else if(MagicS=="Peralay"){
      summon("Peralay", fX, fY, fZ, "Peralay");
    } else if(MagicS=="Ringlerun"){
      summon("Ringlerun", fX+300, fY, fZ, "Ringlerun");
    } else if(MagicS=="Char"){
      summon("Char", fX, fY, fZ, "Char");
    } else if(MagicS=="Sarken"){
      summonSarken(fX, fY, fZ);
    }
}

For a menu, there's this shop I triggered in the game, a guy that sells stuff for bows.

Code:
name		Bowyer
score		0 -1
health		100
speed		0
nomove		1
type		enemy
gfxshadow	1
nodrop		1
defense		all 0
noatflash	1
nolife		1
animationscript	data/scripts/villager.c


anim idle
	loop	1
	delay	50
	offset	32 84
	bbox    22 10 25 75
	frame	data/chars/misc/civilian/merchant/bowyer.png

anim pain
	delay	5
	offset	32 84
	frame	data/chars/misc/civilian/merchant/bowyer.png
	delay	42
	@cmd	spawnDial 160 0 206 320
	frame	data/chars/misc/civilian/merchant/bowyer.png
	delay	52
	frame	data/chars/misc/civilian/merchant/bowyer.png

Inside villager.c

Code:
void spawnDial(float fX, float fY, float fZ, int Edge)
{//Spawns dialogue next to caller
// Spawned dialogue matches entity's alias
 //fX: X location adjustment
 //fY: Y location adjustment
 //fZ: Z location adjustment
 //Edge: Screen length (not used)

   void self = getlocalvar("self"); //Get calling entity
   char Name = getentityproperty(self,"name");
	
   spawn06(Name, fX, fY, fZ); //Spawn dialogue
}

void spawnAlias(char Name, float fX, float fY, float fZ, char Alias)
{//Spawns entity next to caller
 //Name: Entity to be spawned
 //fX: X location adjustment
 //fY: Y location adjustment
 //fZ: Z location adjustment
 //Alias: It's alias

   void Spawn;
	
   Spawn = spawn01(Name, fX, fY, fZ); // Spawn                 
   changeentityproperty(Spawn, "name", Alias); // Change alias
}

Searching for Bowyer with Notepad++, I found it's alias, BowyerD

Code:
name		BowyerD
type		none
facing		1
palette		none
setlayer 	10000
animationscript	data/scripts/shop/shopS.c
script		data/scripts/shop/bowshop.c


anim idle
	delay	6
	offset	160 206
	@cmd	DeControl 0 1
	@cmd	DeControl 1 1
	@cmd	noplayerJoin 1
	frame	data/chars/dialogues/1.png
	frame	data/chars/dialogues/2.png
	frame	data/chars/dialogues/3.png
	delay	200
	frame	data/chars/dialogues/shop/bowyer1.png
	frame	data/chars/dialogues/shop/bowyer2.png
	delay	4
	frame	data/chars/dialogues/4.png
	frame	data/chars/dialogues/5.png
	frame	data/chars/dialogues/6.png
	frame	data/chars/dialogues/7.png
	frame	data/chars/dialogues/8.png
	frame	data/chars/dialogues/9.png
	@cmd	spawnHand "Hand1" 0 120 80 200 320 0
	@cmd	spawnHand "Hand2" 1 200 80 200 320 1
	frame	data/chars/dialogues/shop/bowyer3.png
	delay	20000
	frame	data/chars/dialogues/shop/bowyer3.png
	delay	4
	@cmd	killHand 0
	@cmd	killHand 1
	frame	data/chars/dialogues/9.png
	frame	data/chars/dialogues/8.png
	frame	data/chars/dialogues/7.png
	frame	data/chars/dialogues/6.png
	frame	data/chars/dialogues/5.png
	frame	data/chars/dialogues/4.png
	delay	100
	frame	data/chars/dialogues/shop/bowyer4.png
	delay	6
	frame	data/chars/dialogues/3.png
	frame	data/chars/dialogues/2.png
	frame	data/chars/dialogues/1.png
	delay	16
	@cmd	DeControl 0 0
	@cmd	DeControl 1 0
	@cmd	noplayerJoin 0
	@cmd	suicide
	frame	data/chars/misc/empty.gif

Bowshop.c

Code:
void main()
{// Update script for displaying hand in bowyer & handles what hand shows
    void vSelf = getlocalvar("self"); //Get player
    void vAniPos = getentityproperty(vSelf, "animpos"); //Get current animation frame
    int XPos = openborvariant("xpos");

    void Hand1 = getentityvar(vSelf, 0);
    void Hand2 = getentityvar(vSelf, 1);

    void iJump1 = playerkeys(0, 1, "jump");
    void iJump2 = playerkeys(1, 1, "jump");

    int x1;
    int y1;
    int x2;
    int y2;

    if(Hand1){ 
      x1 = getentityproperty(Hand1,"x"); //Get Hand1's x coordinate
      y1 = getentityproperty(Hand1,"a"); //Get Hand1's y coordinate

//      drawstring(150,110,1,x1-XPos);
//      drawstring(150,150,1,y1);

      if(vAniPos==12){
        if(x1 >= XPos + 55 && x1 <= XPos + 170 && y1 >= 110 && y1 <= 125){
          setentityvar(Hand1, 0, "Crossbow");
          setentityvar(Hand1, 1, 5000);
          setentityvar(Hand1, 2, "Magic");
          setentityvar(Hand1, 3, NULL());
//          drawstring(150,140,1,"Crossbow");
        } else if(x1 >= XPos + 55 && x1 <= XPos + 150 && y1 >= 85 && y1 <= 100){
          setentityvar(Hand1, 0, "1");
          setentityvar(Hand1, 1, 100);
          setentityvar(Hand1, 2, "Bolt");
          setentityvar(Hand1, 3, NULL());
//          drawstring(150,140,1,"Bolt");
        } else if(x1 >= XPos + 55 && x1 <= XPos + 165 && y1 >= 60 && y1 <= 75){
          setentityvar(Hand1, 0, "2");
          setentityvar(Hand1, 1, 200);
          setentityvar(Hand1, 2, "Bolt");
          setentityvar(Hand1, 3, NULL());
//          drawstring(150,140,1,"Fire_Bolt");
        } else if(x1 >= XPos + 55 && x1 <= XPos + 180 && y1 >= 35 && y1 <= 50){
          setentityvar(Hand1, 0, "3Arrow");
          setentityvar(Hand1, 1, 5000);
          setentityvar(Hand1, 2, "Magic");
          setentityvar(Hand1, 3, NULL());
//          drawstring(150,140,1,"Triple_Arrows");
        } else if(x1 >= XPos + 145 && x1 <= XPos + 175 && y1 >= 15 && y1 <= 25){
          setentityvar(Hand1, 0, NULL());
          setentityvar(Hand1, 1, NULL());
          setentityvar(Hand1, 2, "Menu");
          setentityvar(Hand1, 3, 13);
//          drawstring(150,140,1,"EXIT");
        } else {
          setentityvar(Hand1, 0, NULL());
          setentityvar(Hand1, 1, NULL());
          setentityvar(Hand1, 2, NULL());
          setentityvar(Hand1, 3, NULL());
        } 
        if(iJump1){          
          updateframe(vSelf, 13);
        }
      }
    }

    if(Hand2){
      x2 = getentityproperty(Hand2,"x"); //Get Hand2's x coordinate
      y2 = getentityproperty(Hand2,"a"); //Get Hand2's y coordinate

      if(vAniPos==12){
        if(x2 >= XPos + 55 && x2 <= XPos + 170 && y2 >= 110 && y2 <= 125){
          setentityvar(Hand2, 0, "Crossbow");
          setentityvar(Hand2, 1, 5000);
          setentityvar(Hand2, 2, "Magic");
          setentityvar(Hand2, 3, NULL());
        } else if(x2 >= XPos + 55 && x2 <= XPos + 150 && y2 >= 85 && y2 <= 100){
          setentityvar(Hand2, 0, "1");
          setentityvar(Hand2, 1, 100);
          setentityvar(Hand2, 2, "Bolt");
          setentityvar(Hand2, 3, NULL());
        } else if(x2 >= XPos + 55 && x2 <= XPos + 165 && y2 >= 60 && y2 <= 75){
          setentityvar(Hand2, 0, "2");
          setentityvar(Hand2, 1, 200);
          setentityvar(Hand2, 2, "Bolt");
          setentityvar(Hand2, 3, NULL());
        } else if(x2 >= XPos + 55 && x2 <= XPos + 180 && y2 >= 35 && y2 <= 50){
          setentityvar(Hand2, 0, "3Arrow");
          setentityvar(Hand2, 1, 5000);
          setentityvar(Hand2, 2, "Magic");
          setentityvar(Hand2, 3, NULL());
        } else if(x2 >= XPos + 145 && x2 <= XPos + 175 && y2 >= 15 && y2 <= 25){
          setentityvar(Hand2, 0, NULL());
          setentityvar(Hand2, 1, NULL());
          setentityvar(Hand2, 2, "Menu");
          setentityvar(Hand2, 3, 13);
        } else {
          setentityvar(Hand2, 0, NULL());
          setentityvar(Hand2, 1, NULL());
          setentityvar(Hand2, 2, NULL());
          setentityvar(Hand2, 3, NULL());
        } 
        if(iJump2){          
          updateframe(vSelf, 13);
        }
      }
    }
}

Check next post for the other script, they went over the character limit.

x)
 
I'm back, been sidetracked for most of the day(it's been over 12 hours since I last posted).
It took me sometime to get copy everything I think I needed correctly, my main PC keeps freezing or turning itself off for some reason so using laptop, I got this thing to work(Screenshot below). One thing I haven't figured out yet, what part of the script determines the position of the cursor? I thought it was "if(x == Px-75 && y == 116)" but when I changed 75 to 65, the cursor wouldn't respond to anything but attack 2.
Also, I'd like yo active this menu by pressing attack3 and 4 at the same time. Never used 2 button commands before, but this is something I could use with other mods. Unless you're using offset, which I just thought about.

EDIT:
After messing around with it, I figured out how to move the cursor to the exact spots on the menu as the chars. I think from this point on, I just need to fix it up for the rest. I will so this presents a bit of a problem when I add more characters, not only will I have to change the whole menu, but rewrite the coding as well. While this is still good for Beast Mode, I may need to change this for other mods. I'm think of switching between looped animations as Beastie said, that show 5 chars at a time so you have a chance to see who's up next from left and right of the selected char. I'll see if I can figure this out for myself later, I'm taking it break for now. Also making a copy of what I worked on so far in case anyone wants to see.
Code:
anim	idle
@script
  if(frame>=1){
    void self = getlocalvar("self");
    int x = getentityproperty(self,"x");
    int y = getentityproperty(self,"y");
    void Par = getentityvar(self, 2);
    int Px = getentityproperty(Par,"x");
    int PIndex = getentityproperty(Par,"playerindex");
    int C1 = getglobalvar(PIndex+"A"); // gets attack pressed status
    int X1 = getglobalvar(PIndex+"X"); // gets left or right pressed status
    int Y1 = getglobalvar(PIndex+"Y"); // gets up or down pressed status
    int SFX = loadsample("data/sounds/ganti.wav");

    if(x == Px-75 && y == 116){ // Sonic
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW1")); // selected elf
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px-51); // moves to right
        setglobalvar(PIndex+"X", NULL());
      }
    } else if(x == Px-51 && y == 116){ // Tails
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW2")); // selected fighter
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px-75); // moves to left
        setglobalvar(PIndex+"X", NULL());
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px-27); // moves to right
        setglobalvar(PIndex+"X", NULL());
      } else if(Y1<0){ // down is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", NULL(), NULL(), 76); // moves to bottom
        setglobalvar(PIndex+"Y", NULL());
      }
    } else if(x == Px-25 && y == 76){ // at bottom middle left 
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW5")); // selected trooper
      } else if(Y1>0){ // up is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", NULL(), NULL(), 116); // moves to top
        setglobalvar(PIndex+"Y", NULL());
      }
    } else if(x == Px-27 && y == 116){ // Knuckles
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW3")); // selected knight
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px-51); // moves to left
        setglobalvar(PIndex+"X", NULL());
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px-3); // moves to right
        setglobalvar(PIndex+"X", NULL());
      }
    } else if(x == Px-3 && y == 116){ // Sally
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW4")); // selected barbarian
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px-27); // moves to left
        setglobalvar(PIndex+"X", NULL());
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px+21); // moves to right
        setglobalvar(PIndex+"X", NULL());
      }
    } else if(x == Px+21 && y == 116){ // Bunnie
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW4")); // selected barbarian
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px-3); // moves to left
        setglobalvar(PIndex+"X", NULL());
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px+45); // moves to right
        setglobalvar(PIndex+"X", NULL());
      }
    } else if(x == Px+45 && y == 116){ // Nicole
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW4")); // selected barbarian
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px+21); // moves to left
        setglobalvar(PIndex+"X", NULL());
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px+69); // moves to right
        setglobalvar(PIndex+"X", NULL());
      }
    } else if(x == Px+69 && y == 116){ // Sonia
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW4")); // selected barbarian
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px+45); // moves to left
        setglobalvar(PIndex+"X", NULL());
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        changeentityproperty(self, "position", Px+69); // moves to right
        setglobalvar(PIndex+"X", NULL());
      }
    }
  }
@end_script

EDIT2: Made a new, smaller menu, that only goes left and right, as I described before.

x)

[attachment deleted by admin]
 
Back again. I changed the coding somewhat to fit my new menu.  Rather then the position of the cursor, I'm switching this to the current frame, though pressing attack still goes to follow animation. I want to get this to switch the frame by pressing left or right, but I don't know the exact command for that and searching didn't help. This is what I got so far.
Code:
@script
  if(frame == 1){ // Sonic
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW1")); // selected Sonic
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        switchframe>=2
      }
  if(frame == 2){ // Tails
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW2")); // selected Tails
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        switchframe>=3
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        switchframe>=1
      }
	loop	1
	delay	1
	offset	34 39
	frame	data/chars/Menu/NSel0.gif
	delay	90000
	frame	data/chars/Menu/NSel0.gif
	frame	data/chars/Menu/NSel1.gif
	frame	data/chars/Menu/NSel2.gif
	frame	data/chars/Menu/NSel3.gif
	frame	data/chars/Menu/NSel4.gif
	frame	data/chars/Menu/NSel5.gif
	frame	data/chars/Menu/NSel6.gif
	frame	data/chars/Menu/NSel7.gif
	frame	data/chars/Menu/NSel8.gif
	frame	data/chars/Menu/NSel9.gif

I would also need to know how I can make " @cmd beidle" also command going back to the right frame, so it doesn't go back to the first one automatically.

x)
 
Glad you could learn something from this simple menu :)
I added a trooper icon in bottom line to show that menu can have more lines instead of just one

Now for this:
I would also need to know how I can make "  @cmd  beidle" also command going back to the right frame, so it doesn't go back to the first one automatically.

This is beidle function:
Code:
void beidle()
{// Go to IDLE animation!
    void self = getlocalvar("self");

    setidle(self, openborconstant("ANI_IDLE"));
}

I'm using this to return to IDLE animation. However, for cursor like this, I think changing animation to IDLE with other function such as performattack or changeentityproperty should work

switchframe>=2

You can change that with this:

Code:
updateframe(self, 2);
 
Bloodbane said:
Glad you could learn something from this simple menu :)
I added a trooper icon in bottom line to show that menu can have more lines instead of just one
I'm glad to, only took a few hours of staring at it.  ;) I did notice that second line, which was a good call because that how I originally planned that out, though I didn't think ahead and account for adding new characters.

Now for this:
I would also need to know how I can make "  @cmd  beidle" also command going back to the right frame, so it doesn't go back to the first one automatically.

This is beidle function:
Code:
void beidle()
{// Go to IDLE animation!
    void self = getlocalvar("self");

    setidle(self, openborconstant("ANI_IDLE"));
}

I'm using this to return to IDLE animation. However, for cursor like this, I think changing animation to IDLE with other function such as performattack or changeentityproperty should work
I can see this, but what about making to a set frame like the updateframe code you gave me?

Also, tried running this and I get an error.
Code:
anim	idle
@script
  if(frame == 1){ // Sonic
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW1")); // selected Sonic
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        updateframe(self, 2);
      }
  if(frame == 2){ // Tails
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW2")); // selected Tails
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        updateframe(self, 3);
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        updateframe(self, 1);
      }
  if(frame == 3){ // Knuckles
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW2")); // selected Knuckles
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        updateframe(self, 3);
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        updateframe(self, 2);
      }
    }
  }
@end_script
The error
Code:
Script compile error in 'animationscript': C1 line 9, column 9

********** An Error Occurred **********
*            Shutting Down            *

Can't compile script 'animationscript' data/chars/Menu/NPCSel1.txt

looked for line and column 9 in lescript
Code:
void offscreenkill( float dx, int E )
{// Check position relative to screen. If enemy is offscreen, suicide!
//  dx : Distance to screen edge
//  E  : Edge selection, 0 = left, 1 = right

    voi[b]d[/b] self = getlocalvar("self");
The specified point is "d" in void.
Maybe I'm getting this because I change the script from what it was originally for? IDK.

x)
 
You removed important lines that's why you got that error. These are the missing lines:
    void self = getlocalvar("self");
    void Par = getentityvar(self, 2);
    int PIndex = getentityproperty(Par,"playerindex");
    int C1 = getglobalvar(PIndex+"A"); // gets attack pressed status
    int X1 = getglobalvar(PIndex+"X"); // gets left or right pressed status

These lines are for acquiring pressed or released state of attack and left or right key
 
I was at a loss last night, but today I added "Else if" to the other 2 frames and now the game finally loads up. My new menu comes up nicely, but I don't get a response when I press anything but attack 2 to close it.

Here's the change I made to Knuckles animation:
Code:
	@cmd	spawnBind2 "NPCSel1" 0 60 -1 2 0 1
	@cmd	spawnChild "NPCSel0" -75 116 1 1 1 2
I switch the names in " ", so the control you had over the cursor goes to the menu itself to switch frames, while the cursor spawns, when I set it right, in the middle to show who you have selected.

Here's the menu or NPCSel1 setup as of now.
Code:
anim	idle
@script
  if(frame == 0){ // 
    void self = getlocalvar("self");
    void Par = getentityvar(self, 2);
    int PIndex = getentityproperty(Par,"playerindex");
    int C1 = getglobalvar(PIndex+"A"); // gets attack pressed status
    int X1 = getglobalvar(PIndex+"X"); // gets left or right pressed status
    int SFX = loadsample("data/sounds/ganti.wav");

  if(frame == 1){ // Sonic
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW1")); // selected Sonic
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        updateframe(self, 2);
      }
    } else if(frame == 2){ // Tails
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW2")); // selected Tails
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        updateframe(self, 3);
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        updateframe(self, 1);
      }
    } else if(frame == 3){ // Knuckles
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW2")); // selected Knuckles
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        updateframe(self, 3);
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        updateframe(self, 2);
      }
    }
  }
@end_script
	loop	1
	delay	1
	offset	112 96
	frame	data/chars/Menu/NSel0.gif
	delay	90000
	frame	data/chars/Menu/NSel0.gif
	frame	data/chars/Menu/NSel1.gif
	frame	data/chars/Menu/NSel2.gif
	frame	data/chars/Menu/NSel3.gif
	frame	data/chars/Menu/NSel4.gif
	frame	data/chars/Menu/NSel5.gif
	frame	data/chars/Menu/NSel6.gif
	frame	data/chars/Menu/NSel7.gif
	frame	data/chars/Menu/NSel8.gif
	frame	data/chars/Menu/NSel9.gif

x)
 
Yeah, I kept them there before I changed the idle animation and it's script.

Code:
anim	follow1
	delay	5
	offset	34 39
	frame	data/chars/Menu/Sel0.gif
	sound	data/sounds/beep2.wav
	frame	data/chars/Menu/Sel1.gif
	@cmd	spawnN "RASH_N" -60 0 0 1 "RASH"
	frame	data/chars/Menu/Sel0.gif
	frame	data/chars/Menu/Sel1.gif
	@cmd	beidle
	frame	data/chars/Menu/Sel0.gif

The other 4 follow animatins are the same, aside from what's being spawned. Dunno what else needs to be done, unless there needs to be a change in lescript or something.

x)
 
Yeah, I copied the file. Here it is if you think it needs to be looked over.
Code:
void main()
{
    int iPlIndex = getlocalvar("player"); //Get Player's index
    void vSelf = getlocalvar("self"); //Get player
    void vAniID = getentityproperty(vSelf,"animationID"); //Get current animation ID
    void vAniPos = getentityproperty(vSelf, "animpos"); //Get current animation frame

    void iUp = playerkeys(iPlIndex, 1, "moveup"); // New key status of "Up"
    void iDown = playerkeys(iPlIndex, 1, "movedown"); // New key status of "Down"
    void iLeft = playerkeys(iPlIndex, 1, "moveleft"); // New key status of "Left"
    void iRight = playerkeys(iPlIndex, 1, "moveright"); // New key status of "Right"
    void iAttack = playerkeys(iPlIndex, 1, "attack");// New key status of "Attack"
    void iAttack2 = playerkeys(iPlIndex, 1, "attack2");// New key status of "Attack2"
    void iAttack3 = playerkeys(iPlIndex, 1, "attack3");// New key status of "Attack3"
    void iAttack4 = playerkeys(iPlIndex, 1, "attack4");// New key status of "Attack4"
    void iSpecial = playerkeys(iPlIndex, 1, "special");// New key status of "Special"
    void iJump = playerkeys(iPlIndex, 1, "jump");// New key status of "Jump"
    void iStart = playerkeys(iPlIndex, 1, "start");// New key status of "Start"

    void iUpR = playerkeys(iPlIndex, 2, "moveup"); // Release status of "Up"
    void iDownR = playerkeys(iPlIndex, 2, "movedown"); // Release status of "Down"
    void iLeftR = playerkeys(iPlIndex, 2, "moveleft"); // Release status of "Left"
    void iRightR = playerkeys(iPlIndex, 2, "moveright"); // Release status of "Right"
    void iAttackR = playerkeys(iPlIndex, 2, "attack");// Release status of "Attack"
    void iAttack2R = playerkeys(iPlIndex, 2, "attack2");// Release status of "Attack2"
    void iAttack3R = playerkeys(iPlIndex, 2, "attack3");// Release status of "Attack3"
    void iAttack4R = playerkeys(iPlIndex, 2, "attack4");// Release status of "Attack4"
    void iJumpR = playerkeys(iPlIndex, 2, "jump");// Release status of "Jump"
    void iStartR = playerkeys(iPlIndex, 2, "start");// Release status of "Start"

    void iUpH = playerkeys(iPlIndex, 0, "moveup"); // Held key status of "Up"
    void iDownH = playerkeys(iPlIndex, 0, "movedown"); // Held key status of "Down"
    void iLeftH = playerkeys(iPlIndex, 0, "moveleft"); // Held key status of "Left"
    void iRightH = playerkeys(iPlIndex, 0, "moveright"); // Held key status of "Right"

// Movement event capture
    if(iLeft){ //Left is pressed?
      setglobalvar(iPlIndex+"X", -1);
    } else if(iRight){ //Right is pressed?
      setglobalvar(iPlIndex+"X", 1);
    }
    if(iUp){ //Up is pressed?
      setglobalvar(iPlIndex+"Y", 1);
    } else if(iDown){ //Down is pressed?
      setglobalvar(iPlIndex+"Y", -1);
    }

    if(iLeftR || iRightR){ //Left or Right is released?
      setglobalvar(iPlIndex+"X", 0);
    }
    if(iUpR || iDownR){ //Up or Down is released?
      setglobalvar(iPlIndex+"Y", 0);
    }

// Action event capture
    if(iAttack){ //Attack is pressed?
      setglobalvar(iPlIndex+"A", 1);
    }
    if(iAttackR){ //Attack is released?
      setglobalvar(iPlIndex+"A", NULL());
    }

    if(iAttack2){ //Attack2 is pressed?
      setglobalvar(iPlIndex+"A2", 1);
    }
    if(iAttack2R){ //Attack2 is released?
      setglobalvar(iPlIndex+"A2", NULL());
    }

    if(iAttack3){ //Attack3 is pressed?
      setglobalvar(iPlIndex+"A3", 1);
    }
    if(iAttack3R){ //Attack3 is released?
      setglobalvar(iPlIndex+"A3", NULL());
    }

    if(iAttack4){ //Attack4 is pressed?
      setglobalvar(iPlIndex+"A4", 1);
    }
    if(iAttack4R){ //Attack4 is released?
      setglobalvar(iPlIndex+"A4", NULL());
    }

    if(iJump){ //Jump is pressed?
      setglobalvar(iPlIndex+"J", 1);
    }
    if(iJumpR){ //Jump is released?
      setglobalvar(iPlIndex+"J", NULL());
    }

    if(iStart){ //Start is pressed?
      setglobalvar(iPlIndex+"St", 1);
    }
    if(iStartR){ //Start is released?
      setglobalvar(iPlIndex+"St", NULL());
    }
}

x)
 
DJ, I figured out the cause of the problem and I have to tell this bad news. Your method of using frames with long delay is incompatible with the script :(

The reason Curs entity has a very short delay i.e 2 centiseconds is because it needs to be responsive to player's key press. In your method, the delay is 90000 centiseconds or 900 seconds or 15 minutes which means for the menu to respond to player's key press, it has to wait for 15 minutes

You'll have to change the method OR use updatescript to acquire key press instead
 
Damn, ok then, what about Beastie's idea of switching between looping follow animations? The script for each one could be something like this:
Code:
  if(frame == 1){ // Sonic
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW101")); // selected Sonic
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        performattack(self, openborconstant("ANI_FOLLOW2")); // selects Tails
      }
I don't think I'll have over 100 selectable chars but this may be easier to keep up with, especially when I have to change what order they are in to fit the menu.

EDIT:
Tried making a script this way but it crashes the engine and doesn't tell me why in the log. Here's what I did(Idle and Follow1 have the same script so another Follow animation go back to 1 if needed)
Code:
anim	idle
@script
  if(frame>=0){
    void self = getlocalvar("self");
    int x = getentityproperty(self,"x");
    int y = getentityproperty(self,"y");
    void Par = getentityvar(self, 2);
    int Px = getentityproperty(Par,"x");
    int PIndex = getentityproperty(Par,"playerindex");
    int C1 = getglobalvar(PIndex+"A"); // gets attack pressed status
    int X1 = getglobalvar(PIndex+"X"); // gets left or right pressed status
    int Y1 = getglobalvar(PIndex+"Y"); // gets up or down pressed status
    int SFX = loadsample("data/sounds/ganti.wav");

  if(frame == 2){ // Sonic
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW101")); // selected Sonic
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        performattack(self, openborconstant("ANI_FOLLOW2")); // selects Tails
      }
    }
  }
@end_script
	loop	 1
	delay	1
	offset	117 66
	frame	data/chars/Menu/NSel0.gif
	frame	data/chars/Menu/NSel0.gif
	delay	15
	frame	data/chars/Menu/NSel0.gif

anim	follow1
@script
  if(frame>=0){
    void self = getlocalvar("self");
    int x = getentityproperty(self,"x");
    int y = getentityproperty(self,"y");
    void Par = getentityvar(self, 2);
    int Px = getentityproperty(Par,"x");
    int PIndex = getentityproperty(Par,"playerindex");
    int C1 = getglobalvar(PIndex+"A"); // gets attack pressed status
    int X1 = getglobalvar(PIndex+"X"); // gets left or right pressed status
    int Y1 = getglobalvar(PIndex+"Y"); // gets up or down pressed status
    int SFX = loadsample("data/sounds/ganti.wav");

  if(frame == 2){ // Sonic
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW101")); // selected Sonic
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        performattack(self, openborconstant("ANI_FOLLOW2")); // selects Tails
      }
    }
  }
@end_script
	loop	 1
	delay	1
	offset	117 66
	frame	data/chars/Menu/NSel0.gif
	frame	data/chars/Menu/NSel0.gif
	delay	15
	frame	data/chars/Menu/NSel0.gif

anim	follow101
	delay	5
	offset	34 39
	frame	data/chars/Menu/Sel0.gif
	sound	data/sounds/beep2.wav
	frame	data/chars/Menu/Sel1.gif
	@cmd	spawnN "RASH_N" -60 0 0 1 "RASH"
	frame	data/chars/Menu/Sel0.gif
	frame	data/chars/Menu/Sel1.gif
	@cmd	beidle
	frame	data/chars/Menu/Sel0.gif

anim	follow2
@script
  if(frame>=0){
    void self = getlocalvar("self");
    int x = getentityproperty(self,"x");
    int y = getentityproperty(self,"y");
    void Par = getentityvar(self, 2);
    int Px = getentityproperty(Par,"x");
    int PIndex = getentityproperty(Par,"playerindex");
    int C1 = getglobalvar(PIndex+"A"); // gets attack pressed status
    int X1 = getglobalvar(PIndex+"X"); // gets left or right pressed status
    int Y1 = getglobalvar(PIndex+"Y"); // gets up or down pressed status
    int SFX = loadsample("data/sounds/ganti.wav");

  if(frame == 2){ // Tails
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW102")); // selected Tails
      } else if(X1>0){ // right is pressed?
        playsample(SFX, 0, 120, 120, 100, 0);
        performattack(self, openborconstant("ANI_FOLLOW3")); // selects Knuckles
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 1, 120, 120, 100, 0);
        performattack(self, openborconstant("ANI_FOLLOW1")); // selects Sonic
      }
    }
  }
	loop	 1
	delay	1
	offset	117 66
	frame	data/chars/Menu/NSel1.gif
	frame	data/chars/Menu/NSel1.gif
	delay	15
	frame	data/chars/Menu/NSel1.gif

anim	follow102
	delay	5
	offset	34 39
	frame	data/chars/Menu/Sel0.gif
	sound	data/sounds/beep2.wav
	frame	data/chars/Menu/Sel1.gif
	@cmd	spawnN "ZITZ_N" -60 0 0 1 "FZITZ"
	frame	data/chars/Menu/Sel0.gif
	frame	data/chars/Menu/Sel1.gif
	@cmd	beidle
	frame	data/chars/Menu/Sel0.gif

anim	follow3
@script
  if(frame>=0){
    void self = getlocalvar("self");
    int x = getentityproperty(self,"x");
    int y = getentityproperty(self,"y");
    void Par = getentityvar(self, 2);
    int Px = getentityproperty(Par,"x");
    int PIndex = getentityproperty(Par,"playerindex");
    int C1 = getglobalvar(PIndex+"A"); // gets attack pressed status
    int X1 = getglobalvar(PIndex+"X"); // gets left or right pressed status
    int Y1 = getglobalvar(PIndex+"Y"); // gets up or down pressed status
    int SFX = loadsample("data/sounds/ganti.wav");

  if(frame == 2){ // Knuckles
      if(C1==1){
        setglobalvar(PIndex+"A", NULL());
        performattack(self, openborconstant("ANI_FOLLOW103")); // selected Knuckles
      } else if(X1<0){ // left is pressed?
        playsample(SFX, 1, 120, 120, 100, 0);
        performattack(self, openborconstant("ANI_FOLLOW2")); // selects Tails
      }
    }
  }
	loop	 1
	delay	1
	offset	117 66
	frame	data/chars/Menu/NSel2.gif
	frame	data/chars/Menu/NSel2.gif
	delay	15
	frame	data/chars/Menu/NSel2.gif

anim	follow103
	delay	5
	offset	34 39
	frame	data/chars/Menu/Sel0.gif
	sound	data/sounds/beep2.wav
	frame	data/chars/Menu/Sel1.gif
	@cmd	spawnN "PIMPLE_N" -60 0 0 1 "PIMPLE"
	frame	data/chars/Menu/Sel0.gif
	frame	data/chars/Menu/Sel1.gif
	@cmd	beidle
	frame	data/chars/Menu/Sel0.gif
x)
 
You really want to use 100 FOLLOWS?

Anyways, I asked that cause if you do, you need to expand follows limit with maxfollows in models.txt first. Otherwise, you got that crash
 
I forgot about setting max follows, but I just opened up my models txt and saw that it's already set to 200. I don't remember why but it's there. Yeah though, I figured that linking them this way would make it easier to keep track rather then every character having 2 or 3 numbers higher then the next. Honestly though, I've given this some thought and wonder if this is really about the delay, because the menu still reacted to going left and right, just not performing the attacks.

Let's say I go back to my previous setup(which I made a copy of) and do what you suggested, "use updatescript to acquire key press instead", what all would I need for that, and wasn't this what Keyall was for and have the coding for?
Code:
void main()
{
    int iPlIndex = getlocalvar("player"); //Get Player's index
    void vSelf = getlocalvar("self"); //Get player
    void vAniID = getentityproperty(vSelf,"animationID"); //Get current animation ID
    void vAniPos = getentityproperty(vSelf, "animpos"); //Get current animation frame

    void iUp = playerkeys(iPlIndex, 1, "moveup"); // New key status of "Up"
    void iDown = playerkeys(iPlIndex, 1, "movedown"); // New key status of "Down"
    void iLeft = playerkeys(iPlIndex, 1, "moveleft"); // New key status of "Left"
    void iRight = playerkeys(iPlIndex, 1, "moveright"); // New key status of "Right"
    void iAttack = playerkeys(iPlIndex, 1, "attack");// New key status of "Attack"
    void iAttack2 = playerkeys(iPlIndex, 1, "attack2");// New key status of "Attack2"
    void iAttack3 = playerkeys(iPlIndex, 1, "attack3");// New key status of "Attack3"
    void iAttack4 = playerkeys(iPlIndex, 1, "attack4");// New key status of "Attack4"
    void iSpecial = playerkeys(iPlIndex, 1, "special");// New key status of "Special"
    void iJump = playerkeys(iPlIndex, 1, "jump");// New key status of "Jump"
    void iStart = playerkeys(iPlIndex, 1, "start");// New key status of "Start"

    void iUpR = playerkeys(iPlIndex, 2, "moveup"); // Release status of "Up"
    void iDownR = playerkeys(iPlIndex, 2, "movedown"); // Release status of "Down"
    void iLeftR = playerkeys(iPlIndex, 2, "moveleft"); // Release status of "Left"
    void iRightR = playerkeys(iPlIndex, 2, "moveright"); // Release status of "Right"
    void iAttackR = playerkeys(iPlIndex, 2, "attack");// Release status of "Attack"
    void iAttack2R = playerkeys(iPlIndex, 2, "attack2");// Release status of "Attack2"
    void iAttack3R = playerkeys(iPlIndex, 2, "attack3");// Release status of "Attack3"
    void iAttack4R = playerkeys(iPlIndex, 2, "attack4");// Release status of "Attack4"
    void iJumpR = playerkeys(iPlIndex, 2, "jump");// Release status of "Jump"
    void iStartR = playerkeys(iPlIndex, 2, "start");// Release status of "Start"

    void iUpH = playerkeys(iPlIndex, 0, "moveup"); // Held key status of "Up"
    void iDownH = playerkeys(iPlIndex, 0, "movedown"); // Held key status of "Down"
    void iLeftH = playerkeys(iPlIndex, 0, "moveleft"); // Held key status of "Left"
    void iRightH = playerkeys(iPlIndex, 0, "moveright"); // Held key status of "Right"

// Movement event capture
    if(iLeft){ //Left is pressed?
      setglobalvar(iPlIndex+"X", -1);
    } else if(iRight){ //Right is pressed?
      setglobalvar(iPlIndex+"X", 1);
    }
    if(iUp){ //Up is pressed?
      setglobalvar(iPlIndex+"Y", 1);
    } else if(iDown){ //Down is pressed?
      setglobalvar(iPlIndex+"Y", -1);
    }

    if(iLeftR || iRightR){ //Left or Right is released?
      setglobalvar(iPlIndex+"X", 0);
    }
    if(iUpR || iDownR){ //Up or Down is released?
      setglobalvar(iPlIndex+"Y", 0);
    }

// Action event capture
    if(iAttack){ //Attack is pressed?
      setglobalvar(iPlIndex+"A", 1);
    }
    if(iAttackR){ //Attack is released?
      setglobalvar(iPlIndex+"A", NULL());
    }

    if(iAttack2){ //Attack2 is pressed?
      setglobalvar(iPlIndex+"A2", 1);
    }
    if(iAttack2R){ //Attack2 is released?
      setglobalvar(iPlIndex+"A2", NULL());
    }

    if(iAttack3){ //Attack3 is pressed?
      setglobalvar(iPlIndex+"A3", 1);
    }
    if(iAttack3R){ //Attack3 is released?
      setglobalvar(iPlIndex+"A3", NULL());
    }

    if(iAttack4){ //Attack4 is pressed?
      setglobalvar(iPlIndex+"A4", 1);
    }
    if(iAttack4R){ //Attack4 is released?
      setglobalvar(iPlIndex+"A4", NULL());
    }

    if(iJump){ //Jump is pressed?
      setglobalvar(iPlIndex+"J", 1);
    }
    if(iJumpR){ //Jump is released?
      setglobalvar(iPlIndex+"J", NULL());
    }

    if(iStart){ //Start is pressed?
      setglobalvar(iPlIndex+"St", 1);
    }
    if(iStartR){ //Start is released?
      setglobalvar(iPlIndex+"St", NULL());
    }
}

x)
 
because the menu still reacted to going left and right, just not performing the attacks.

That's strange cause it should take really long to respond to those key press
Are you using updatescript for this menu?

do what you suggested, "use updatescript to acquire key press instead", what all would I need for that, and wasn't this what Keyall was for and have the coding for?

keyall.c is for acquiring key press / release status to be used by non player entities. Just leave it be
I just realized that I said it wrong. It should be use updatescript to respond to key press.
Anyways, to make updatescript, create a blank .c file then move the animation script you have made there. Don't forget to add animation check to ensure key press/release is only taken when menu is in IDLE
 
Had some internet issues over the past few days so I was able to get back on.

Bloodbane said:
That's strange cause it should take really long to respond to those key press
Are you using updatescript for this menu?
No, update script is being used for unlocking characters when certain bosses are killed.

do what you suggested, "use updatescript to acquire key press instead", what all would I need for that, and wasn't this what Keyall was for and have the coding for?

keyall.c is for acquiring key press / release status to be used by non player entities. Just leave it be
I just realized that I said it wrong. It should be use updatescript to respond to key press.
Anyways, to make updatescript, create a blank .c file then move the animation script you have made there. Don't forget to add animation check to ensure key press/release is only taken when menu is in IDLE
Ok, I'll leave Keyall alone, but the animation script, if you mean for the menu, that would be lescript, which I just did. I'll try experimenting now.

EDIT:
Don't know what animation check is but I'll try to look.

x)
 
Ok, I know this was over a year old but I've taken a break on any serious modding and thought it was about time I got back on this menu, apologies for leaving it like this for such a long spell and no resolving it.

I really had no clue what I was doing from last I left off, and I had tried to change the script but it wasn't working out, so I downloaded Bloodbane's map demo from before redid the menu and cursor to what we first worked on(Screenshot below). Right now I've got the cursor to move to and from every char icon on the menu. I still need to make it properly spawn every character, that I can do later, but the main three things I really need to do with this are these:
1. I need some script to spawn the icons for locked chars based on if their flagged as unlocked.
2. Come up with a button sequence for spawning it, I'm just using attack 4 right now. Though I could probably just use attack 1 and 2 together.
3. Spawning the menu from a fixed position so it's not based on where the player is, as it could easily have icons off screen.

EDIT:
Disregard #2, I'm using a quick chargeattack to summon the menu, button combinations were hard to execute.

x)

[attachment deleted by admin]
 
Back
Top Bottom