[Solved] Double inventory, droping items + was: Making objects solid

Started by Cassiebsg, Fri 06/06/2014 22:36:42

Previous topic - Next topic

Cassiebsg

Okay, am not sure this is the correct forum to post this, so please forgive me if it's not.

I finally created a few objects for my game and I stumbled into a "common problem", namely that my character can walkover the objects. My first thought was turn the object solid. But there's no option for it. Then I thought: "I can just create a non walkable area around my object, and turn it walkable once he picks the object up." However, I want my character to be able to drop the object when and if he wants, so that wouldn't work... After some search on the forum and manual I found there's a script line for that. Fine! So try that... not working! I wanted to put it on the Globals scripts so it would work in every room... After a day of reading more, I found that line seem to only work when in the room script. Rats, cause I wanted it to be true in whatever room the character is! :(

Here's my current code for room1:

Code: ags

function room_RepExec()
{
oSuitcase.Solid = true;
oSuitcase.BlockingHeight = 7;
oSuitcase.BlockingWidth = 45;
}


Is there any way I can make this true in every room? Besides copy/paste this into every room he may have the suitcase in?

And my other question is: why isn't this an option that one can just check in the object's properties?

PS: I'm using Build 3.3.0.1156, and default game.
There are those who believe that life here began out there...

Mandle

Try this in the Global Script:

Object[5].Solid = true;

(Assuming the suitcase is object #5)

Then do the same thing for the other object properties you mentioned.

You must refer to objects by number, not name, in global script. ;)

Khris

The main problem here is that objects are bound to rooms. Which means an object that can be dropped everywhere must be created for every room separately.
The only alternative to this is to use characters, because they are global. One could add a custom property to characters, something like "is_object", then use that to allow the game to figure out whether the character is an actual person or a droppable object. This solves the issue, because all solid properties can now be set in game_start().
(Short of creating a custom walkable area/pathfinding system, there is no other way to turn arbitrary parts of walkable areas solid, at least none that I know of.)


Cassiebsg

Mandle, unfortunately your method doesn't work for me... either I'm putting it in the wrong place, don't know what am doing (true!) or something else, but I get the following error: fixed sized array cannot be used in this way.

Will try Khris method on another object, a backpack. :)
There are those who believe that life here began out there...

Khris

Just for reference, Mandle's code uses "Object", but the global array is "object".
This would work: object[5].Solid = true;

Cassiebsg

#5
Hey. Sorry about the delay, been meaning to thank you two for this! :)
Mandle's code with Khris correction works perfectly! :)

I had just hoped I had manged to do the backpack as a character, but that one is turning to be also much more complicated than I first thought it would be... guess I'm currently coding complicated stuff, instead of taking care of the "easy" stuff first... lol

I did however created my backpack character, and I can pick it up and add it to inventory, so no problem there (and yes, he's solid!). :) I just hadn't realized that dropping an object/character would be so hard to do.

I'll post what I want to do, please just say if my logic is wrong or if I can't do it like I'm thinking to do. No point loosing a month or so trying to code something that is "broken" at start. ;)

1. Select backpack from inventory.
2. click it on the screen to drop it.
    2a. Check that mouse click coordinates are on walkable area.
    2b. Check that mouse click coords. are not in a walk behind area.
    2c. Save mouse coordinates as backpack coords. (or maybe this one should be 2a?)
3. Lose inventory item backpack.
4. Add backpack sprite to saved coord.
5. If player now wants to pick it up again, then use the saved coords. as walk to point.

The other problem, is having 2 inventory windows (the standard one with limited space + backpack)... (and of course not having the backpack inventory if player has dropped the backpack)...
I'm trying to follow this help thread to solve it (http://www.adventuregamestudio.co.uk/forums/index.php?topic=36291.msg476491#msg476491). I thought of 2 methods, but method 1 (using the backpack from inside the inventory window to open the 2nd inventory GUI) doesn't seem to work as I can't figure out how to add the interact mode in there... besides seems a bit unintuitive and annoying as game play goes. So that enters 2nd method I thought off: add a new button to the main GUI (gIconbar). that will open the 2nd inventary GUI, though only if the player has the backpack in the main inventory...

Hope it makes sense... would it be possible to do this? Or my way of thinking is "broken" and would not work in AGS?
There are those who believe that life here began out there...

Khris

Dropping a character is much easier. Step 2c would simply place the character at the mouse coordinates, that way you don't have to store them elsewhere. It's basically just: cBackpack.ChangeRoom(player.Room, mouse.x + GetViewportX(), mouse.y + GetviewportY());
This also takes care of step 4 (which is a huge issue if you don't use a character).

The only problem here is inventory management, mostly because you can't set an item as ActiveInventory unless the player actually carries it.
Which means AGS will crash as soon as the player tries to pick up an item from the backpack inventory.

There are several ways to fix this:
1. add all backpack items to the player's inv when they pick up the backpack, remove them when it is dropped.
2. implement a custom mouse.mode with the backpack inventory item as cursor graphic. Picking an item and clicking a hotspot would have to be handled manually, and the hotspots can no longer rely on if (player.ActiveInventory == iKnife), they'd have to use a custom function (not terribly inconvenient, something like if (UsedItem(iKnife)) will work fine. Just a hassle to implement in a game halfway done).
3. temporarily add the picked item to the player's inv. Incrementing player.InventoryQuantity[iKnife.ID] should prevent the crash, but as an added bonus should not immediately update the inventory window.

Cassiebsg

#7
Thanks again Khris! :)
I haven't worked on the drop problem yet, as been busy with getting the inventory GUIs to work first. But it's nice to know that is is a bit simpler than I originally thought.

I just got to the crash part, but at least I got both GUI working and showing ATM. :)
Was thinking/going to try to change the player character to the cBackpack when the backpack inventory window is opens, then add the selected item to the player cJake and after clicking ok to close the window and return to the game, change the player to cJake again. Do you think something in those lines would work? Then again, re-reading what you wrote, sounds a bit like your point 3.

EDIT: Changing characters and adding the inventory to cJake works, so I now can go into my backpack inventory, grab my suitcase add it to cJake's and return the character back to cJake.
Am though strugling with finding in the manual how I: refer to the selected item to add to cJake (am currently using iSuitecase cause that's the only item I have, but need to add the one actually selected by the player); setting the new item as the active mouse mode (and show up it the little "selected item" window of the iconbar); and set the mouse mode to it (that gets lost when i change back to cJake). Think that's about it that am missing to get this working (besides a bunch of ifs and elses).

PPS - Argh... seems like your little code actually has the solution to part of my problem (player.room)... oh well, will try it tomorrow. It's bed time now. :(
There are those who believe that life here began out there...

Khris

I hadn't thought of changing the player character to the backpack, that's a cool solution ;-D
Why would you still add the item to cJake though? That's not necessary any longer as far as I can see.
You just need to switch the player back to cJake first thing inside the interaction codes, otherwise you can't use player.Say() and the like anymore.

Cassiebsg

Guess cause my logic says: use cJake for play game, use cBackpack only when accessing inventory. Have a feeling that the code may get messy otherwise. But guess I could let the player use the cBackpack to finish his action with the item, and return to cJake afterwards... will have to think about it. :)
In the mean time I'll go back to trying to figure out how to do what I originally thought, just for the sake of the challenge and learning, if nothing else. ;)
There are those who believe that life here began out there...

Cassiebsg

#10
Alleluia!

This is fun! Even if frustrating at points (don't think the manual is that user frendly, specially if one doesn't know much about programming and AGS) .

But anyway, I finally managed to get my code working! (Am still missing adding the drop item, since I have yet not figured how to get cJake to walk to the item/character without using x,y coordinates... is it even possible to do something like "walkt.to.character?" or do I always need to set the x,y cords?

Anyway, I managed to get Jake to grab his backpack and suitcase.
There are two icon on the iconbar GUI, one for the normal inventory (Jakes) and another for the backpack. The GUI for the backpack inv.window only opens if Jake his carrying his backpack. The backpack is set as a character, once grabbed I changed it's view to one of a blank sprite (annoying that I need to create 4 loops for it work), and set the backpack character to follow cJake (this assures that when opening the GUI for the backpack, it remains in the current player room).
Now for test purposes, I've added the suitcase to the backpack, I can now select it, close the backpack GUI, and keep the suitcase both as the active item and mouse mode. :) And for the sake of fun, I can also now add items that are on cJake's inventory into the backpack inventory. So I'm happy!
I'm thinking later on to set the cJakes inventory to 2 or 4 pocket slots + 2 hand slots, so that it makes sense to have a backpack!

Code: ags


// Backpack Inventory


function btnIconInv2_OnClick(GUIControl *control, MouseButton button)
{
   if ( player.HasInventory (iBackpack)) 
   {
    // Change player to oBackpack and open it's inventory window
    character[25].SetAsPlayer();
    gInvBackpack.Visible = true;
    // switch to the Use cursor (to select items with)
    mouse.Mode = eModeInteract;
    // But, override the appearance to look like the arrow
    mouse.UseModeGraphic(eModePointer);
   }
    else // If player does not have Backpack in inventory
    {
    Display("You do not have a backpack!");
    }
}

function btnInv2OK_Click(GUIControl *control, MouseButton button) {
	// They pressed the OK button, close the GUI
  gInvBackpack.Visible = false;
  if ( player.ActiveInventory != null)
  {
  character[0].AddInventory(player.ActiveInventory);0 // cJake gets the selected item in his inventory
  character[0].ActiveInventory = character[25].ActiveInventory; // Sets the cJake's active inventory identical to what was selected by the player
  character[25].LoseInventory(player.ActiveInventory); // Removes selected item from Backpack
  }
  character[0].SetAsPlayer(); // Sets cJake as player
  mouse.UseModeGraphic(mouse.Mode); 
  mouse.Mode = eModeUseinv;// Changes mouse mode to current seleted item
}


function btnInvUp2_Click(GUIControl *control, MouseButton button) {
  invCustomInv.ScrollUp();
}

function btnInvDown2_Click(GUIControl *control, MouseButton button) {
  invCustomInv.ScrollDown();
}

function btnInvSelect2_Click(GUIControl *control, MouseButton button) {
  
	// They pressed SELECT, so switch to the Get cursor
	mouse.Mode = eModeInteract;
	// But, override the appearance to look like the arrow
	mouse.UseModeGraphic(eModePointer);
}

function iBackpack_Look()
{
  player.Say("It's my backpack! I usually cary it around on... wait for it... my back!");
}

function iBackpack_UseInv()
{
  if ( player.ActiveInventory == iBackpack) // Check if player has the backpack seleted
  { 
    player.Say("I can't put my backpack inside it self!!");
  }
  else // If backpack is not selected than adds selected item to backpack inventory.
  {
    oBackpack.AddInventory(player.ActiveInventory);
    cJake.LoseInventory(player.ActiveInventory);
    player.Say("There! I've put it in my backpack!");
  }
}

function oBackpack_Interact ()
{
// Grabs backpack and adds it to inventory
cJake.Walk(294,  420,   eBlock, eWalkableAreas);
cJake.AddInventory(iBackpack);
oBackpack.ChangeView(26); // Sets the Backpack character as blank/invisible view
oBackpack.FollowCharacter(cJake,  2,  2);
}


Feel free to use or improve my code. :)

PS - Ah! I was thinking too complicated! No need for a walk.to.character option or saving mouse coordinates, all I need to is use the mouse.x and mouse.y options (thanks again Khris!)... of course, that the mouse pointer is actually over the backpack/item that one wants to pick up! Logic! Dumb me for taking so long to figure that one out! Oh dear! I now fear that all my inventory items will be droppable anywhere! This kid is going to end up littering where ever he goes! ;)
There are those who believe that life here began out there...

SMF spam blocked by CleanTalk