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)
 
ShopS.c

Code:
#include "data/scripts/library/spawn.h"

void suicide()
{ // Suicide!!
    void self = getlocalvar("self");

    killentity(self); //Suicide!
}

void beidle()
{// Go to IDLE animation!
    void self = getlocalvar("self");

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

void layer(int layer)
{// Set's enemy's layer
    void self = getlocalvar("self");
    changeentityproperty(self, "setlayer", layer);
}

void spawnHand(void Name, int Index, float fX, float fY, float fZ, int Edge, int Num)
{//Spawns hand next to caller
 //fX: X location adjustment relative to left edge
 //fY: Y location adjustment
 //fZ: Z coordinate

   void self = getlocalvar("self"); //Get calling entity
   void vSpawn; //Spawn object
   void P = getplayerproperty(Index, "entity");

   if(P){
     vSpawn = spawn06(Name, fX, fY, fZ); //Spawn hand
     setentityvar(self, Num, vSpawn);
     setentityvar(vSpawn, 4, self);
   }
}

void spawnCover(void Name, float fX, float fY, float fZ, int Edge, int Num, char Status)
{//Spawns cover next to caller only when defined status is empty or 0
 //fX: X location adjustment relative to left edge
 //fY: Y location adjustment
 //fZ: Z coordinate
 //Edge: Screen length

   void self = getlocalvar("self"); //Get calling entity
   void vSpawn; //Spawn object
   void S = getglobalvar(Status);

   if(S == NULL() || S == 0){
     vSpawn = spawn05(Name, fX, fY, fZ, Edge); //Spawn cover
     setentityvar(self, Num, vSpawn);
   }
}

void spawnText(void Name, float fX, float fY, float fZ, int Num)
{//Spawns text next to caller
 //fX: X location adjustment relative to left edge
 //fY: Y location adjustment
 //fZ: Z coordinate

   void self = getlocalvar("self"); //Get calling entity
   void vSpawn; //Spawn object

   vSpawn = spawn06(Name, fX, fY, fZ); //Spawn text
   setentityvar(self, Num, vSpawn);
}

void killHand(int Num)
{ // Kill hand or cover based on number
    void self = getlocalvar("self");
    void Hand = getentityvar(self, Num);

    if(Hand){
      killentity(Hand);
    }
}

void DeControl(int P, int Flag)
{// Activates or deactivates control for defined player
// P : Player index starting from 0
// Flag : Control flag
    int Player = getplayerproperty(P, "entity");

    if (Player != NULL()){
      changeentityproperty(Player,"noaicontrol",Flag);
    }
}

void noplayerJoin (int iG)
{// controls if other players can join the game or not
// 1 - players CAN NOT join, 0 play CAN join
// remember to set it 0 when you are done, or you will have a 1P only game.
// Douglas Baldan/O Ilusionista - 20/09/14

   changeopenborvariant("nojoin", iG);
}

void spawnDialog(char Name, float fX, float fY, float fZ, void Ani)
{//Spawns dialogue next to caller
 //Name: Name of dialog to be spawned
 //fX: X location adjustment
 //fY: Y location adjustment
 //fZ: Z location adjustment
 //Ani: Animation to play for the dialog

   void Spawn;
	
   Spawn = spawn06(Name, fX, fY, fZ); //Spawn dialogue
   changeentityproperty(Spawn, "animation", openborconstant(Ani));
}

void changeframe(int Num)
{// Change current frame
    void self = getlocalvar("self"); //Get calling entity
    updateframe(self, Num);
}

void giveitem(char Item, int Num, void Ani)
{// Gives item to certain player
// Item : Name of given item
// Num : Quantity of given item
// Ani : Animation to play if player is refused

    void self = getlocalvar("self"); //Get calling entity
    int Talker1 = getglobalvar("0Talk");
    int Talker2 = getglobalvar("1Talk");
    int SFX = loadsample("data/sounds/nomoney.wav");
    int PIndex;
    int ItemS;
    void Item0;
    void ItemC;
    int ItemQ;
    int ItemLim;
    int i = 1;
    int j = 1;

    if(Talker1==1 || (Talker1==NULL() && Talker2==NULL() )){
      PIndex = 0;
    } else if(Talker2==1){
      PIndex = 1;
    }

    ItemS = getglobalvar(PIndex+"2");

    if(ItemS==NULL()){
      ItemS = 1;
    }

    while(i < 16){ // Check all slots for same item
      ItemC = getglobalvar(PIndex+"3"+i); // Check stored item in i slot

      if(ItemC == Item){ //Found same item in 1 slot
        ItemQ = getglobalvar(PIndex+"4"+i); //Get quantity of item in i slot
        if(ItemQ==NULL()){
          ItemQ = 0;
        }
        if(Item=="CuthbertMc"){ // List of single items
          ItemLim = 1;
        } else {
          ItemLim = 9;
        }

        if(ItemQ>=ItemLim){
          playsample(SFX, 0, 120, 120, 100, 0);
          changeentityproperty(self, "animation", openborconstant(Ani));
        } else {
          setglobalvar(PIndex+"4"+i, ItemQ+Num); // Increment its quantity
        }
        i = 19; //ends loop right away
      }
      i++;
    }

    if(i!=20){ // Loop ends without finding same item
      Item0 = getglobalvar(PIndex+"3"+ItemS); //Get currently stored item in slot

      if(Item0 == NULL()){ // Current item slot is empty
        setglobalvar(PIndex+"3"+ItemS, Item); // Store item in selected slot
        setglobalvar(PIndex+"4"+ItemS, Num); // Set its quantity to 1
      } else {

        while(j < 16){ // Check all slots for empty slot
          ItemC = getglobalvar(PIndex+"3"+j); // Check stored item in j slot

          if(ItemC == NULL()){ //Found an empty slot

            setglobalvar(PIndex+"3"+j, Item); // Store item in j slot
            setglobalvar(PIndex+"4"+j, Num); // Set its quantity to 1
            j = 19; //ends loop right away
          }
          j++;
        }

        if(j!=20){ // Loop ends without finding empty slot
          playsample(SFX, 0, 120, 120, 100, 0);
          changeentityproperty(self, "animation", openborconstant(Ani));
        }
      }
    }
}

void spawnTP(void vName, float fX, float fY, float fZ, int Index)
{
	//Spawns entity on a defined player entity
	//vName: Model name of entity to be spawned in.
	//fX: X distance relative to left edge
	//fY: Y height from ground
	//fZ: Z coordinate
	//Index: Index of player entity to be spawn onto

	void vSpawn; //Spawn object

	clearspawnentry(); //Clear current spawn entry
	setspawnentry("name", vName); //Acquire spawn entity by name
	int Target = getplayerproperty(Index, "entity");

    if(Target){
      fX = fX + getentityproperty(Target, "x"); //Get X location and add adjustment.
      fY = fY + getentityproperty(Target, "a"); //Get Y location and add adjustment.
      fZ = fZ + getentityproperty(Target, "z"); //Get Z location and add adjustment.
	
	vSpawn = spawn(); //Spawn in entity.

	changeentityproperty(vSpawn, "position", fX, fZ, fY); //Set spawn location.
    }
}
// Inventory display functions
void spawnIcon(void Name, float fX, float fY, float fZ, int Num, char Alias)
{//Spawns Icon next to caller
 //fX: X location adjustment relative to left edge
 //fY: Y location adjustment
 //fZ: Z coordinate
    void self = getlocalvar("self"); //Get calling entity
    int XPos = openborvariant("xpos");
    int x = getentityproperty(self, "x");
    void vSpawn; //Spawn object

    vSpawn = spawn01(Name, fX, fY, fZ); //Spawn text
    changeentityproperty(vSpawn, "name", Alias);
    setentityvar(self, Num, vSpawn);

    if(x==XPos+240){
      setentityvar(vSpawn, 0, 1);
    } else {
      setentityvar(vSpawn, 0, 0);
    }
}

void InventIcon()
{ // Spawns icons on 2nd page of Inventory screen
    void self = getlocalvar("self");
    int XPos = openborvariant("xpos");
    int x = getentityproperty(self, "x");
    int i;
    int j = 1;
    int Index;
    void vSpawn;

    if(x==XPos+240){
      Index = 1;
    } else {
      Index = 0;
    }

    for(j=1; j<=10; j++){
      i = 1;
      for(i=1; i<=3; i++){
        IconSelect(i, j, Index);
      }
    }
}

void killIcons(int Limit)
{ // Kill all stored icons
    void self = getlocalvar("self");
    void Gun;
    int i = 1;

    for(i=1; i<=Limit; i++){
      Gun = getentityvar(self, i);

      if(Gun){
        killentity(Gun);
      }
    }
}

void IconSelect(int i, int j, int Index)
{// Select icons to display
    void self = getlocalvar("self");
    void Num = getlocalvar("Order" + self);
    void Name;
    void Check;

    if(Num==NULL()){
      Num = 1;
    }

    if(Num==1){
      Check = "BEye";
    } else if(Num==2){
      Check = "ClericHat";
    } else if(Num==3){
      Check = "ClockworkKit";
    } else if(Num==4){
      Check = "DBSkin"; // 1. Gained 2. Sold
    } else if(Num==5){
      Check = "DrEgg";
    } else if(Num==6){
      Check = "DrHorn";
    } else if(Num==7){
      Check = Index + "ArmorP";
    } else if(Num==8){
      Check = Index + "ArmorB";
    } else if(Num==9){
      Check = "Gears";
    } else if(Num==10){
      Check = "Girdle";
    } else if(Num==11){
      Check = "GolHeart";
    } else if(Num==12){
      Check = "GreenDiamond"; // 1. Gained 2. Given
    } else if(Num==13){
      Check = Index + "Ogre";
    } else if(Num==14){
      Check = "MCSkin"; // 1. Gained 2. Sold
    } else if(Num==15){
      Check = "OBEgg"; // 0. Sold  1. Gained
    } else if(Num==16){
      Check = "OblivionOrb";
    } else if(Num==17){
      Check = "PowerCore";
    } else if(Num==18){
      Check = "Powder";
    } else if(Num==19){
      Check = "Rao"; // 1. Gained Crook of Rao 2. Banished Demons
    } else if(Num==20){
      Check = Index + "RingF";
    } else if(Num==21){
      Check = Index + "RingP";
    } else if(Num==22){
      Check = "Ruby";
    } else if(Num==23){
      Check = "ShieldDr";
    } else if(Num==24){
      Check = "ShieldF";
    } else if(Num==25){
      Check = "ShieldI";
    } else if(Num==26){
      Check = Index + "ArmorS";
    } else if(Num==27){
      Check = "VecnaEye"; // 0. Given  1. Gained
    } else if(Num>=28){
      Check = "None";
    }

    if(Check == "DBSkin" || Check == "GreenDiamond" || Check == "MCSkin" || Check == "OBEgg" || Check == "Rao" || Check == "VecnaEye"){
      if(getglobalvar(Check) == 1){
        Name = IconName(Num);
        spawnIcon("InvIcon2", i*32-80, 162-j*16, 0, Num, Name);
        setlocalvar("Order" + self, Num + 1);
      } else if(Num<29){
        setlocalvar("Order" + self, Num + 1);
        IconSelect(i, j, Index);
      }
    } else if(Num == 7 || Num == 8 || Num == 26){
      if(getglobalvar(Check) == 0.5){
        Name = IconName(Num);
        spawnIcon("InvIcon2", i*32-80, 162-j*16, 0, Num, Name);
        setlocalvar("Order" + self, Num + 1);
      } else if(Num<29){
        setlocalvar("Order" + self, Num + 1);
        IconSelect(i, j, Index);
      }
    } else if(Check!="None" && getglobalvar(Check)){
      Name = IconName(Num);
      spawnIcon("InvIcon2", i*32-80, 162-j*16, 0, Num, Name);
      setlocalvar("Order" + self, Num + 1);
    } else if(Num<29){
      setlocalvar("Order" + self, Num + 1);
      IconSelect(i, j, Index);
    }
}

void IconName(int Num)
{ // Selects proper name based on number
    if(Num==1){
      return "BEye";
    } else if(Num==2){
      return "ClericHat";
    } else if(Num==3){
      return "ClockKit";
    } else if(Num==4){
      return "DBSkin";
    } else if(Num==5){
      return "DrEgg";
    } else if(Num==6){
      return "DrHorn";
    } else if(Num==7){
      return "Earring";
    } else if(Num==8){
      return "FKalung";
    } else if(Num==9){
      return "Gears";
    } else if(Num==10){
      return "Girdle";
    } else if(Num==11){
      return "GolHeart";
    } else if(Num==12){
      return "GreenD";
    } else if(Num==13){
      return "Ogre";
    } else if(Num==14){
      return "MCSkin";
    } else if(Num==15){
      return "OBEgg";
    } else if(Num==16){
      return "Orb";
    } else if(Num==17){
      return "PowCore";
    } else if(Num==18){
      return "Powder";
    } else if(Num==19){
      return "RaoCrook";
    } else if(Num==20){
      return "RingF";
    } else if(Num==21){
      return "RingP";
    } else if(Num==22){
      return "Ruby";
    } else if(Num==23){
      return "ShiDr";
    } else if(Num==24){
      return "ShiFl";
    } else if(Num==25){
      return "ShiIce";
    } else if(Num==26){
      return "SKalung";
    } else if(Num==27){
      return "VecEye";
    }
}
// File manage functions + load model function
void fileread(void Path)
{// Read values from file defined with Path then store each value in each entity variable
      void self = getlocalvar("self");
      void file = openfilestream(Path, 1);
      void vLoad;
      int i = 0;

      if( file != -1 ){
        setfilestreamposition(file, 0);
        vLoad = getfilestreamargument(file, 0, "string");

        while(vLoad != "#End"){
          setentityvar(self, i, vLoad);
          i = i + 1;
          filestreamnextline(file);
          vLoad = getfilestreamargument(file, 0, "string");
        }

        if(vLoad == "#End"){
          setentityvar(self, i, vLoad);
          closefilestream(file);
        }
        return 1;
      } else {
        return -1;
      }
}

void fileedit(void Path, char Name, void Value)
{// Read values from entity variables, find the one matching with Name then change the value in next line
      void self = getlocalvar("self");
      int Check = fileread(Path);
      int i;
      void vLoad;

      if(Check==1){
        i = 0;
        vLoad = getentityvar(self, i);

        while(vLoad != Name && vLoad != "#End" && vLoad != NULL()){
          i = i + 1;
          vLoad = getentityvar(self, i);
        }

        if(vLoad == Name){
          i = i + 1;
          vLoad = getentityvar(self, i);
          setentityvar(self, i, Value);
        }
      }
}

void filewrite(void Path)
{// Read values from entity variables then write them to a file by name Path
// Must use fileread function first
      void self = getlocalvar("self");
      int i = 0;
      void vLoad = getentityvar(self, i);

      if(vLoad){
        void file = createfilestream();
        filestreamappend(file, vLoad, 1);

        while(vLoad != "#End" && vLoad != NULL()){
          i = i + 1;
          vLoad = getentityvar(self, i);
          filestreamappend(file, vLoad, 0);
        }

        savefilestream(file, Path);
        closefilestream(file);
      }
}

void writedefault(void Path)
{// Writes file by name Path with default values
// Used when there's no file to start with
      void file = createfilestream();
      filestreamappend(file, "CavLock", 1);
      filestreamappend(file, 0, 0);
      filestreamappend(file, "BardLock", 0);
      filestreamappend(file, 0, 0);
      filestreamappend(file, "#End", 0);

      savefilestream(file, Path);
      closefilestream(file);
}

void Unlock(int Flag, void Path)
{ // Unlocks certain character based on flag and write the status on file named Path
// 1: Unlocks Cavalier
// 2: Unlocks Bard
    void file;
    char Code;
    int Value;

    if(Flag == 1){
      Code = "CavLock";
      Value = 31;
    } else {
      Code = "BardLock";
      Value = 1221;
    }

    if(Code && Value){
      file = openfilestream(Path, 1);
      if(file == -1){
        writedefault(Path);
      }
      closefilestream(file);

      fileedit(Path, Code, Value);
      filewrite(Path);
    }
}

Looking at all this, I'm thinking what I want to do is have playable characters an animaiton to start spawnDial like Bowyer. What I'm having trouble understanding is what the hands are hitting to conform the item your buying from the shop. Anyway, I think this is most of it, I noticed this line, "#include "data/scripts/library/spawn.h" so I'll post that in a following post so I don't accidently exceed the character limit for posting. Also, I'm attaching the image used for the shop, and the char icons from Sonic Revolution to get an idea on my own menu.

[attachment deleted by admin]
 
Oh this wasn't a tutorial, I'm asking if anyone could look at the script and see if they can figure out what it is I need to do to apply it for my needs.

On that note, I missed a script, Hand.C, which I can't copy the whole thing cause I know it exceeds the limit, but after looking around, I found this:
Code:
void Hire(int PIndex)
{// Hire Sarken Mercenary
    void self = getlocalvar("self"); //Get calling entity
    int Gold = getglobalvar(PIndex+"Gold");
    int Sarkens = getglobalvar(PIndex+"Sarken");
    int Price = getentityvar(self,1);
    int SFX = loadsample("data/sounds/buy.wav");
    int SFX2 = loadsample("data/sounds/nomoney.wav");

    if(Sarkens==NULL()){
      Sarkens = 0;
    }

    if(Gold >= Price && Sarkens < 9){
      setglobalvar(PIndex+"Sarken", Sarkens + 1);
      setglobalvar(PIndex+"Gold", Gold - Price);
      playsample(SFX, 0, 120, 120, 100, 0);
    } else {
      playsample(SFX2, 0, 120, 120, 100, 0);
    }
}

I think coding like this is what I need for spawning, removing the script regarding money and having the script just spawn the character, or even more, do that but spawn another menu at the same time to select another character. I think this is figuring out how the menu works and spawning it from an animation is all I need.

x)
 
Jeremiah Cuff said:
Oh my fault about that man, I thought this a tutorial about summoning characters or something like that. I totally misunderstood the situation at hand, no hard feelings my friend.
Oh, no reason to have hard feelings, and if you get something out of this, that's be cool. As of now, it seems I'll have to try and screw around with it at some point.

x)
 
TBH DJ, shop is really complex feature. More complex than level up script if you ask me cause it involves inventory system and keyall.c (just to name a few)
Also this is just one way to make shop, there are other ways (with script that is)

Now, I can help you make new scripts for this purpose but it would be complex
So let's start from this: when will this menu be shown? in level (in heat of battle) or in shop level?
 
Yeah, I'm aware it's complex, but it's something I've wanted to get done for years. The shop itself isn't my concern, just making a menu for selecting NPC's. If it's gotta be new then so be it. I'd like the menu to show up during gameplay, commanded from an animation somehow, with via @cmd or spawning something else entirely, which ever works better. I still don't know exactly how I would go about triggering the animation though. Maybe by pressing certain buttons at the same time, or using a sequence of follow animations

x)
 
If it's just to spawn NPC's why not just use animations and spawn commands?  I imagine any menu will freeze gameplay anyway, so you could just make the menu using a weapon model of the player (or summoning an entity).  you will still need some basic script commands, but it's fairly straight forward. 

You can use pause script to freeze gameplay except for player 1, then each animation is on loop until a key is pressed.  then just capture keypresses and switch animations accordingly.  keyint script or similar can be used so the current animation is on loop and just waits for key inputs.  Up/Down cycles options in menu, attack selects an option.  Then it would simply run the NPC spawn animation based on selection.  You could have it so it's just button inputs and one screen, Attack 1 spawn npc 1,  A2 spawns npc2 etc. 

The rest of the work would be setting up the sprites.

- pressing button switches model and/or spawns menu entity.
- also freezing gameplay (using pause script)
- player weapon/model would actually be the menu.
- this model would spawn a background panel with 'setlayer' to hide gameplay
- menu elements would be inside the actual player model

Here's something I was doing in my original game, similar setup, except this is just a stats screen, there's nothing to select, only open and close the screen.  But it checks against vars setup in script, so it simply checks these and displays what it should.  Ability icons only display/spawn if you have obtained them for example.  Energy/health meter is consistent with current energy/health.  Current level is also shown, eventually there was going to images for each level etc.  This screen is several entities and panels working together to create the screen.  This way everything can be individually animated and controlled.  Setlayer is used to hide gameplay but still show the HUD.

0094.png


the screen fades to black using a panel entity.  another panel is also spawned for parts of the menu (so they fade in).  setlayer is used in each entity to control what is visible.  additional menu parts are binded entities that are using spawnbind.  Because they're animated I like to have them as their own entities, also I planned to add variations of the abilities too. (like level 1 level 2 level 3 etc. - changing colours and icons accordingly)  anyhow it was only partially complete and some of it is non functional at the moment.

Actually I think in my mod the player is still the normal player, not a weapon model.  'SPECIAL' button just summons the menu entity which freezes everything else, then it just checks vars and stats from the player entity.  So really the game is just paused and everything including player is just hiding behind the panel entities, which is active.

Sorry if this is really vague, working off the top of my head and haven't looked at this or any mod for ages. :(

HTH
 
Sorry if this is really vague, working off the top of my head and haven't looked at this or any mod for ages.
No it's fine man, this has to start someone right? I actually understand much of what you're saying, it's just that when it gets to writing the script or looking at it most of the time, I'm at a loss. I was hoping to force myself into getting better at this at some point.

Shooting in the dark though, I said I wanted to try experimenting a little, but the best I can do is take what I gathered from the D&D mod, which I made shortcuts to a few key files I thought were important, and write what I want in them. I've got something to do though so this will be done quickly.
This is the basis. It's from the Hand script from D&D which I'm pretty sure is given player control during the menu.
Code:
void Hire(int PIndex)
{// Hire Sarken Mercenary
    void self = getlocalvar("self"); //Get calling entity
    int Gold = getglobalvar(PIndex+"Gold");
    int Sarkens = getglobalvar(PIndex+"Sarken");
    int Price = getentityvar(self,1);
    int SFX = loadsample("data/sounds/buy.wav");
    int SFX2 = loadsample("data/sounds/nomoney.wav");

    if(Sarkens==NULL()){
      Sarkens = 0;
    }

    if(Gold >= Price && Sarkens < 9){
      setglobalvar(PIndex+"Sarken", Sarkens + 1);
      setglobalvar(PIndex+"Gold", Gold - Price);
      playsample(SFX, 0, 120, 120, 100, 0);
    } else {
      playsample(SFX2, 0, 120, 120, 100, 0);
    }
}

My rough mock up, calling Shadow the Hedgehog
Code:
void Shadow(int PIndex)
{// Call Shadow
    void self = getlocalvar("self"); //Get calling entity
    int ShadowN = getglobalvar(PIndex+"Shadow");
    int SFX = loadsample("data/sounds/buy.wav");
    int SFX2 = loadsample("data/sounds/nomoney.wav");

    if(ShadowN==NULL()){
      Shadow  = 0;
    }

}

I basically just replaced Sarken with Shadow and removed anything having to do with Money, except sound effects. I figured since the Hand itself uses CMD's in follow animations, I could do the same with Shadow.
Code:
anim follow11
	delay	1
	offset	19 3
	frame	data/chars/misc/hands/hand1.png
	delay	5
	@cmd	dasher 0 0 0
	frame	data/chars/misc/hands/hand1.png
	delay	25
	@cmd	Hire 0
	frame	data/chars/misc/hands/hand2.png
	delay	20
	frame	data/chars/misc/hands/hand1.png
	delay	5
	@cmd	beidle
	frame	data/chars/misc/hands/hand1.png
Mine would be @cmd Shadow 0

If my script is off though, I'd like to know why if you can.

x)
 
Okay then, I'll figure out another way to make menu with OpenBoR
But for now, let me explain this function first:

Code:
void summon(void vName, float fX, float fY, float fZ, void Summon)
{	//Summons entity from left and set them as summoned character
	//
	//vName: Model name of entity to be spawned in.
	//fX: X location adjustment
	//fY: Y location adjustment
        //fZ: Z location adjustment
	//Summon: Summon code

	void self = getlocalvar("self"); //Get calling entity.
        void Child = getglobalvar("S"+Summon);
	int Direction = getentityproperty(self, "direction");
	void vSpawn; //Spawn object.
        int Screen = openborvariant("hResolution"); // Get screen width

	if(Child!="X" && Child<=openborvariant("elapsed_time") - 4000){
	  setglobalvar("S"+Summon, NULL());
          Child = NULL();
        }
	if(Child==NULL()){
//	  vSpawn = spawn04(vName, fX, fY, fZ, Screen); //Spawn in entity.
	   vSpawn = spawn02(vName, fX, fY, fZ, Screen); //Spawn in entity.

	  changeentityproperty(vSpawn, "direction", Direction); //Set direction.
	  setglobalvar("S"+Summon, "X");
        }
}

This function is for spawning helper NPC similar to summonframe. Unlike the latter, this function allows summoning multiple different NPCs instead of just one
This function isn't related to shop/hire NPC stuff
 
@ DJ - I actually meant you won't need to write any scripts using my methods, or only very minor script added to animations, depending on your needs.  You would mainly just need to add existing scripts by Bloodbane/DC to your mod so certain commands are available.

What I meant is you would do everything within an entity and everything is done with animation tricks, spawned entities and setlayer etc.  The scripts I mentioned should be in the Scripts Index or found in other mods easily.  Don't over complicate things, essentially all we want to do is summon/spawn NPC's which is quite easy to do without scripts.  You just want some way to choose them.

So the menu could just be a weapon model for the player, or just a animation within the default player.  A key would be assigned to this animation, for example lets use 'SPECIAL' key.  So when you press special it would run this animation, within this animation it would be our menu graphics.  The animation would be on loop and use pause script to freeze gameplay except for the player.  The menu can be easily animated this way, it can have transparent background and have gameplay visible behind it, or you can spawn a panel entity with setlayer setting so it becomes the background. 

So lets say we can choose 3 NPC's, the first animation is going to be our menu with NPC 1 highlighted, using keyint script command, this animation will be on loop unless it gets certain key inputs. 
Untitled-1.png

So lets say we want ATTACK1 to select our NPC, pressing attack1 causes the animation to switch to another animation, our 'npc summnoning animation'  so within this animation we UNSUMMON any menu elements and summon the selected NPC.  You can go further and have mana/hp cost associated with it.  Otherwise pressing direction will change to the other NPC options, so all your really doing is looping animations to navigate the menu.  So the animations just loop until you press a certain key, the player will only be able to press up and down, attack key to select an option, special key to exit/close the menu.  The whole menu could actually just be a weapon model for player and use freespecials and attacks to make the menu or whatever will select NPCs.

Like Bloodbane said, kinda need more details to know exactly what is required for this NPC function.  What is the cost/penalty associated with summoning them? requires MANA, HP, POINTS ?  or you actually need currency added like it would cost GOLD like in D&D?  Can more NPC's be obtained? is the menu fullscreen or like a popup spell menu like JRPG kinda thing?

Is the menu even needed? Really you just need a way to choose NPC's.  Maybe something like a basic button combination, so UP+A is NPC 1 LEFT + ATTACK is NPC2 etc.  So the menu is really just a visual guide for the player, the rest is done with basic commands.  Or you could just enter a summoning animation, so you just get icon above your head telling you what button combo will spawn which NPC etc.

BTW summoning instead of spawning means the entity is linked to the player/entity that spawned it, so it can be unsummoned with command, but also prevent another NPC being spawned until it dies/gets removed.

@O Ilusionista - thanks man, it's all open source graphics thou so I can't take too much credit  ;)  Was still experimenting with all the layout. 
 
Ok, my bad then. It's funny though, cause while I was at work, I started thinking more on what you said about switching models and weapons, and it starting sounding a lot more simple as I thought on it more. I even got to thinking, hell, maybe I could make a whole custom character select menu this way.  I'll save that for later though.

For now, I'd just like the cover the basics of what you stated here. After I post this, I'll start mocking up a custom menu image, then follow animations for it. BTW, I know there's a Drawsprite command right? Maybe I could get the entities to draw a sprite of the corresponding char for each animation.

There's more I could say, but I'm going to get the basics down as best as I can, before gathering any scripts.

x)
 
Don't over complicate things,
This. Remember the KISS principle. I often forget about it and regret later.
Judging what Beastie said, I think its way easier that way. Yeah, we have a draw sprite, but it need to be updates every tick or it vanishes on the next tick/engine update if I am not wrong.
 
O Ilusionista said:
Don't over complicate things,
This. Remember the KISS principle. I often forget about it and regret later.
Judging what Beastie said, I think its way easier that way. Yeah, we have a draw sprite, but it need to be updates every tick or it vanishes on the next tick/engine update if I am not wrong.
lol, I'll try to remember that. I guess because how complex script is and looks to me, I think that way, so I'll have to think small and simple, then move on from there. Also, thanks for the tip.

About the menu, here's what I made so far, kinda got distracted so this took longer then it really needed. This is a simple txt file for a menu just to get started with.
Code:
name	Menu
type	Panel
shadow	0
alpha   0
remove  0
speed 1
setlayer 10
offscreenkill 5000

animationscript data/scripts/script.c

anim idle
        loop    1
	delay	12
	offset	0 0
	frame	data/chars/Menu/Menu.gif
	frame	data/chars/Menu/Menu.gif
	frame	data/chars/Menu/Menu.gif

anim Follow1 #Sonic
        loop    1
	delay	12
	offset	0 0
	cancel	0 3 0 F Follow2
	cancel	0 3 0 B Follow3
	frame	data/chars/Menu/Menu.gif
	frame	data/chars/Menu/Menu.gif
	frame	data/chars/Menu/Menu.gif

anim Follow2 #Tails
        loop    1
	delay	12
	offset	0 0
	cancel	0 3 0 F Follow3
	cancel	0 3 0 B Follow1
	frame	data/chars/Menu/Menu.gif
	frame	data/chars/Menu/Menu.gif
	frame	data/chars/Menu/Menu.gif

anim Follow3 #Knuckles
        loop    1
	delay	12
	offset	0 0
	cancel	0 3 0 F Follow1
	cancel	0 3 0 B Follow2
	frame	data/chars/Menu/Menu.gif
	frame	data/chars/Menu/Menu.gif
	frame	data/chars/Menu/Menu.gif
		
anim	spawn
	loop	0
	offset	0 0
	delay	5
	sound	data/sounds/spawn.wav
	frame	data/chars/Menu/Menu.gif
	frame	data/chars/Menu/Menu.gif
	frame	data/chars/Menu/Menu.gif

The image itself is a slightly edited image I kept to make easy changes to the char select menu when new characters are added.

x)

[attachment deleted by admin]
 
Back
Top Bottom