Problems with equipable items.

Started by Construed, Tue 08/02/2011 13:04:11

Previous topic - Next topic

Construed

Hello everyone, I'm trying to create an equipable weapon system.
This is the functions im using.
Code: ags

 function repeatedly_execute_always()
   {
Helmet.ManualScaling = true;
player.ManualScaling = true;
player.Scaling = GetScalingAt(player.x,player.y);
Helmet.Scaling = player.Scaling;

Helmet.y = player.y-60;
Helmet.x = player.x;
   }

My problem is that the helmet moves up and down when the character does.
I need to get the helmet posioned on top of the users head where it will use the manual scaling specified, and not move upward and downward when the character does.

Thank you for reading, this has been bothering me for quite some time.
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Gilbert

The problem is that when the scale changes the y-offset of the helmet from the character's feet needs to be scaled also.

Try something like (not tested and I'm not sure if it's the right formula):
Code: ags

Helmet.y = player.y-(player.Scaling*60)/100;


However, the simplest way is to draw the helmet sprites the same size as the character's sprites (just leave blank area below the "floating" helmet so that it will be aligned with the character sprites), and then you don't need to worry about the offsets. Just use "Helmet.y = player.y;" instead.

Construed

#2
Thank you :D that works quite well.

PS. This is the working code for it, may be useful to alot of people.
Code: ags

   function repeatedly_execute_always()
   {

Helmet.y = player.y-(player.Scaling*55)/100;
Helmet.ManualScaling = true;
player.ManualScaling = true;
player.Scaling = GetScalingAt(player.x,player.y);
Helmet.Scaling = player.Scaling;
Helmet.x = player.x;
   }
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Gilbert

Hmmm. Why don't you put the "Helmet.y=..." line at the end like in the original codes? By putting it at the beginning will use the scaling of the last game loop (which may give some small "jumps" to the position of the helmet), since player.Scaling isn't updated yet (you update it a few lines below).

Construed

Ok, i did that.Here is my code so far.
Code: ags

   function repeatedly_execute_always()
   {
     
/////////////////HELMETS//////////////////     
     
Helmet.Baseline=500;
Helmet.ManualScaling = true;
player.ManualScaling = true;
player.Scaling = GetScalingAt(player.x,player.y);
Helmet.Scaling = player.Scaling;
Helmet.Loop=player.Loop;
Helmet.y = player.y-(player.Scaling*53)/100;
Helmet.x = player.x-(player.Scaling*2)/100;
CafeDo(String.Format("helmet is %d", 31));

/////////////////SWORDS////////////////// 
Sword.Baseline=500;
Sword.ManualScaling = true;
player.ManualScaling = true;
player.Scaling = GetScalingAt(player.x,player.y);
Sword.Scaling = player.Scaling;
Sword.Loop=player.Loop;
Sword.y = player.y-(player.Scaling*25)/100;
Sword.x = player.x-(player.Scaling*0)/100;
/////////////////ARMORS////////////////// 
Armor.Baseline=499;
Armor.ManualScaling = true;
player.ManualScaling = true;
player.Scaling = GetScalingAt(player.x,player.y);
Armor.Scaling = player.Scaling;
Armor.Loop=player.Loop;
Armor.y = player.y-(player.Scaling*24)/100;
Armor.x = player.x-(player.Scaling*0)/100;
}


Do you know how i can switch this:

CafeDo(String.Format("helmet is %d", 31));

to send the x,y coords of the helm instead of that view number?
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Khris

You don't need to duplicate every line, you don't need to set ManualScaling to true each loop, and you don't need to set the player's scaling to manual at all if you're then setting his scaling to the scaling level at their current position...

Put this in game_start:

Code: ags
  Helmet.Baseline=500;
  Helmet.ManualScaling = true;
  Sword.Baseline=500;
  Sword.ManualScaling = true;
  Armor.Baseline=499;
  Armor.ManualScaling = true;


Put this in rep_ex_always:

Code: ags
/////////////////HELMETS//////////////////          
  Helmet.Scaling = player.Scaling;
  Helmet.Loop=player.Loop;
  Helmet.x = player.x-(player.Scaling*2)/100;
  Helmet.y = player.y-(player.Scaling*53)/100;

/////////////////SWORDS////////////////// 
  Sword.Scaling = player.Scaling;
  Sword.Loop=player.Loop;
  Sword.x = player.x;
  Sword.y = player.y-(player.Scaling*25)/100;

/////////////////ARMORS////////////////// 
  Armor.Scaling = player.Scaling;
  Armor.Loop=player.Loop;
  Armor.x = player.x;
  Armor.y = player.y-(player.Scaling*24)/100;


To display debug information, put the variables/functions after the text and %d or %f or %s inside the text in the same order:

Code: ags
  CafeDo(String.Format("helmet coords: %d, %d", Helmet.x, Helmet.y));


Construed

Ah, thank you very much chris, I shall try this :D
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Construed

 Ok, The reorganization of the code worked well.
However im trying to send,
Code: ags
    
CafeDo(String.Format("Helmet is %d %d", Helmet2.x, Helmet2.y));

To
Code: ags

 else if ((msg[0] == "Helmet") && (msg[1] == "is"))
    {
    
        this.x = msg[2].AsInt;
        this.y = msg[3].AsInt;
      }      


So the above code converts the int into an action.

Could anyone clarify the correct way of doing this please :D
   
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Khris

What's msg[], a String array?
We need more of the surrounding code.

Construed

String msg[] = action.IRCSplit();
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Khris


Construed

I guess it depends on some function or struct that im unaware of.
Thats a piece of WYZ's source.
I suppose i'll figure it out in due time, Thanks for responding.
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Khris

As far as I understand you want to send a debug command over IRC via Wyz' code.

I take it CafeDo takes a string and sends it to all other clients.
Clientside, that string ends up split into words which are stored in msg[], right?

The code you posted seems to do what you want, the question is, what refers "this" to? Are you coding an extender function for Characters?
What exactly doesn't work?

Construed

This is the entire piece of split script.
Code: ags

void Act(this Character *, String action)
{
    if (action.Length < 1)
      return;
    
    String msg[] = action.IRCSplit();
    if ((msg[0] == "walks") && (msg[1] == "to"))
    {
      if (this.Room == player.Room)
        this.Walk(msg[2].AsInt, msg[3].AsInt, eNoBlock);
      else
      {
        this.x = msg[2].AsInt;
        this.y = msg[3].AsInt;
      }
    }
    else if ((msg[0] == "is") && (msg[1] == "at"))
    {
      if (!this.Moving)
      {
        this.x = msg[2].AsInt;
        this.y = msg[3].AsInt;
      }
    }
    else if ((msg[0] == "looks") && (msg[1] == "like"))
    {
      this.ChangeView(msg[2].AsInt);
    }
        
      /*  
      else if ((msg[0] == "Helmet") && (msg[1] == "is"))
    {
    
        this.x = msg[2].AsInt;
        this.y = msg[3].AsInt;
      }      
*/

    
  //  CafeDo(String.Format("Helmet is %d %d", Helmet2.x, Helmet2.y));
    
}

Note: I commented out the part i was using.
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Khris

Say the client receives: "Bartender walks to 120 170"

I imagine "Bartender" will end up as msg[0], right?
Inside the function, you're comparing msg[0] to verbs but "Helmet" as well, which is it?

Doesn't the client look at msg[0] i.e. "Bartender", then call Bartender.Act("walks to 120 170") ?

In other words, what are you sending to update the Helmet's position?
Also, if it's a multiplayer game, every character is going to need a helmet character.

Construed

CafeDo(String.Format("Helmet is %d %d", Helmet2.x, Helmet2.y));
updates the helmets coordinates,

I just need to figure out how to turn:
        this.x = msg[2].AsInt;
        this.y = msg[3].AsInt;

to

        Helmet.x = msg[2].AsInt;
        Helmet.y = msg[3].AsInt;

"this. equals the player character"
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Khris

Well, what's keeping you from simply using those latter two lines?

.M.M.

You can also use Character.FollowCharacter with parameter FOLLOW_EXACTLY. I use this in my game and it works well.

Construed

#18

.
Quote from: Khris on Fri 11/02/2011 06:37:54
Well, what's keeping you from simply using those latter two lines?
well i guess my main problem is not understanding NPC's which would be "this." and their functions.Something i might have to solve on my own unless someone wants to dig into wyz's source.Right now i guessI'm going to shift focus on the battle engine and work with what i got,thanks for the sorting out we did do :)



Quote from: Mirek on Fri 11/02/2011 07:46:50
You can also use Character.FollowCharacter with parameter FOLLOW_EXACTLY. I use this in my game and it works well.

Yea, thats what I'm using, i was trying to figure out how to send and recieve it server/client
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Khris

I see, well, extender functions work like this:

They are defined with their first parameter being this PointerType*.

Say we want to add a functionality to all Characters, e.g. say "Bye!", then vanish.
What we could do is call this every time:
Code: ags
  cGuy.Say("Bye!");
  cGuy.ChangeRoom(-1);


But if we have to do this a lot and also want to change the message on occasion, it's much more comfortable using an extender function.
We'd do this:

Code: ags
function Vanish(this Character*, String message) {

  this.Say(message);
  this.ChangeRoom(-1);
}


We have now extended the Character object by a new function and call it like this:

Code: ags
  cGuy.Vanish("Bye!");


this in the extender function is pointing to cGuy now, so we are effectively calling the two commands I used further above.
But, if I want to make another character vanish after saying something else, all I need to call is:

Code: ags
  cOtherGuy.Vanish("So long!");


So in the end, it's just another of the many ways to avoid duplicate code.


Now, regarding your problem: you need to give more and preciser info. Which line exactly is sent to the client, and which part of it ends up as action? Also, when is the function called, i.e. where does it say Character.Act(...) in the script?

SMF spam blocked by CleanTalk