Im starting a game, and will probably need quite a bit of scripting help, so I'll make this one thread, and put my questions here as I come up with them.
My first problem is the following:
int tupu = 0;
if (tupu == 0) {Object[0].SetView(7);
tupu++;}
else if (tupu == 1) {Object[0].SetView(8);
tupu--;}
This script gives me an error "variable "[" is already defined." and I have no idea what this means. This script is meant to make a door open when a button is pressed, but if the door is already open, it closes the door.
I am inexperienced with this scripting, but if I'm correct this seems to be very similiar to Java code, with which I have some experience.
Any help, and patience, is truly appreciated.
There may be other problems, but for now it looks like a capitalization error. It should be object[0] not Object[0].
Edit: Does the code actually look like that, or is "int tupu" declared somewhere else, and you just put it there for this post? If this is the actual code, of course the first statement will always be true while the second will never run.
The int tupu; is in this code for now, and thats another problem. I've triedn putting it in global script, but it doesnt work. it just says "undefined symbol 'tupu' ".
EDIT: You were right, the problem was the capital "O":s, but I still cant seem to get the Tupu working.
As it is it is in the global script, and I get the error metioned above.
The other code is in the Room Script, I assume? Then also put "int tupu;" in the top of the room script.
However, I wonder if you need the int at all? Since you're switching between two object view, why not check for the current view instead?
if (object[0].View == 8) {
object[0].SetView(7);
}
else if (object[0].View == 7) {
object[0].SetView(8);
}
Edit: Are you animating the door at all (I don't see any object[0].Animate command)? If you're just switching between two sprites, one opened, one closed, it would be easier just to use object[0].Graphic to change it.
Hahaha!
I realized my mistake: the original defining of "int tupu" was in the wrong place!
Thanks for the help, I think this will get me quite a bit further with my game.
If I need more help, I'll return to this thread in the future.
Here's an even shorter version:
object[0].SetView(15-object[0].View);
Yeah, I'm back again!
This time I have a new problem going on. In my game's intro, I'm trying to get a character to move to the room's door, and to then go to the next room, but when the NPC wlks onto a region (any region, this one is supposed to change the characters lighting as he walks into the light).
How can I get the NPC to walk over these preset regions. The excact error I get says : "Error: Move character: Character not in current room."
I'm simply using the
"cAi1.Say("&3 Get going!");
cAi2.Say("&1 Yes sir!");
character[2].Walk (296, 140);"
script.
Hmm, does the character actually START moving, or does it crash right away?
That error shouldn't have anything to do with Regions ... Obviously enough, it means you're trying to move a character that isn't in the current room. Is character[2] the right character to move?
What's the code for the Region (although, it should reall only be triggered by the player character walking over it)? Is it possible there's something else being triggered that changes the NPC's room, or tries to move another Character?
(Incidentally, to have Regions affect NPCs - for lighting effects, etc - check the NPC's coords against Region.GetAtRommXY (http://www.adventuregamestudio.co.uk/manual/Region.GetAtRoomXY.htm) in rep_ex. It's a little cumbersome, but it's the only way AFAIK.)
FIXXED!!!
Figured out the problem myself.
Now for a simple question: How do I get the script to wait for the last one to have been completed before the next part starts?
Situation now: The NPC starts moving, and as soon as the NPC starts moving the door opens.
Wanted situation: The NPC starts moving, reaches his waypoint near the door, the door opens.
So, what was the problem?
And for the new problem - how about adding the eBlock parameter to Character.Walk?
The problem was mislocating the waypoint of the NPC, so that the NPC was trying to move through a blocking object. Moved waypoint, and had the door actually open so that the NPC wasnt trying to walk through the door, and works fine now.
And I had never heard of eblock before ^^. I've tried reading the tutorials, but I've never bumped into that.
Thanks a buch! Getting back to work!
You can find out about command parameters in the manual, you know ;)
http://www.adventuregamestudio.co.uk/manual/Character.Walk.htm
Ok, I'm back... again...
Does anybody have ideas on how to make this script:
character[0].StopMoving();
cAi1.Say("&1 Ok, lets get moving!");
cAi1.Say("&2 Ellie, I want you to check the containers!");
cAi1.Say("&3 Get going!");
cAi2.Say("&1 Yes sir!");
character[2].Walk (269, 140, eBlock);
object[0].SetView(3);
object[0].Animate(1, 3);
character[2].Walk (313,140);
cAi1.Say("&4 Mike, you have to check the engines.");
character[2].ChangeRoom(10);
object[0].SetView(4);
object[0].Animate(1, 3);
cAi1.Say("&5 You know where they are, so get moving!");
cAi1.Say("&6 I have to get to the command room, and send out the distress signal.");
To only run once in the game.
The script is run when the player steps into a region, but the second time the player steps into the region, the script is run again, and the game crashes because cAi2 is no longer in the room! I was thinking about making a variable that changes from zero into one the first time this is run, but if I put this variable into the room script, it gets defined into zero every time player enters the room!
I've thought about making a second room, otherwise the same than the first, but without this one region, but this seems a bit troublesome.
My guess is that you people have a simple solution here, but it just eludes me...
just turn the region off ;D :
character[0].StopMoving();
cAi1.Say("&1 Ok, lets get moving!");
cAi1.Say("&2 Ellie, I want you to check the containers!");
cAi1.Say("&3 Get going!");
cAi2.Say("&1 Yes sir!");
character[2].Walk (269, 140, eBlock);
object[0].SetView(3);
object[0].Animate(1, 3);
character[2].Walk (313,140);
cAi1.Say("&4 Mike, you have to check the engines.");
character[2].ChangeRoom(10);
object[0].SetView(4);
object[0].Animate(1, 3);
cAi1.Say("&5 You know where they are, so get moving!");
cAi1.Say("&6 I have to get to the command room, and send out the distress signal.");
region[1].Enabled = false;
Why did I just start feeling like a moron?... ;D
Thanks!
But for the future, how can I make a variable that can be called upon any rooms scripts? Is it even possible? I tried setting a variable in the global script, but it couldn't be called upon inside the room. Should it work or was I just... wrong?
int cutscene;
if (cutscene == 0) {
character[0].StopMoving();
cAi1.Say("&1 Ok, lets get moving!");
cAi1.Say("&2 Ellie, I want you to check the containers!");
cAi1.Say("&3 Get going!");
cAi2.Say("&1 Yes sir!");
character[2].Walk (269, 140, eBlock);
object[0].SetView(3);
object[0].Animate(1, 3);
character[2].Walk (313,140);
cAi1.Say("&4 Mike, you have to check the engines.");
character[2].ChangeRoom(10);
object[0].SetView(4);
object[0].Animate(1, 3);
cAi1.Say("&5 You know where they are, so get moving!");
cAi1.Say("&6 I have to get to the command room, and send out the distress signal.");
cutscene++;
}
if you want to make the variable go down:
if (cutscene > 0) { //you put this after your scene natrually
cutscene--;
}
But doesn't this cause the int cutscene to always be zero when read, as it is defined at the start of the script? This is excactly my problem.
Didn't you notice the cutscene++; at the end, but if that doesn't work (because i have kind of the same problem) you could try cutscene+=1; (which probebly wouldn't work anyway) or you could use a GlobalInt eg:
if (GetGlobalInt(1) == 0) {
character[0].StopMoving();
cAi1.Say("&1 Ok, lets get moving!");
cAi1.Say("&2 Ellie, I want you to check the containers!");
cAi1.Say("&3 Get going!");
cAi2.Say("&1 Yes sir!");
character[2].Walk (269, 140, eBlock);
object[0].SetView(3);
object[0].Animate(1, 3);
character[2].Walk (313,140);
cAi1.Say("&4 Mike, you have to check the engines.");
character[2].ChangeRoom(10);
object[0].SetView(4);
object[0].Animate(1, 3);
cAi1.Say("&5 You know where they are, so get moving!");
cAi1.Say("&6 I have to get to the command room, and send out the distress signal.");
SetGlobalInt(1, 1);
}
if you want to make the variable go down:
SetGlobalInt(1, 0);
also making the variable go down is optional, that's just there incase you want it to go down.
(and no, I don't think variables can be called from the global script, I came accross something in the manuel, but it looked REALLY complicated)
if (GetGlobalInt(1) == 0) {
character[0].StopMoving();
cAi1.Say("&1 Ok, lets get moving!");
cAi1.Say("&2 Ellie, I want you to check the containers!");
cAi1.Say("&3 Get going!");
cAi2.Say("&1 Yes sir!");
character[2].Walk (269, 140, eBlock);
object[0].SetView(3);
object[0].Animate(1, 3);
character[2].Walk (313,140);
cAi1.Say("&4 Mike, you have to check the engines.");
character[2].ChangeRoom(10);
object[0].SetView(4);
object[0].Animate(1, 3);
cAi1.Say("&5 You know where they are, so get moving!");
cAi1.Say("&6 I have to get to the command room, and send out the distress signal.");
SetGlobalInt(1, 1);
}
Ok, this code works as it is, but where does it set the variable, as in CREATES the variable?
Does this happen automativcally at GetGlobalInt(1)?
The GlobalInts (
Get/SetGlobalInt are 500 ints hardcoded into AGS. You don't have to create them yourself, they just exist and can be used, well, globally. This is all explained IN THE MANUAL (http://www.adventuregamestudio.co.uk/manual/SetGlobalInt.htm). Please, read it before postng posting other questions (like the
eBlock one) that are answered in there.
Quote
But for the future, how can I make a variable that can be called upon any rooms scripts? Is it even possible?
Quote
(and no, I don't think variables can be called from the global script, I came accross something in the manuel, but it looked REALLY complicated)
Variables declared in Room scripts can't be made Global. Variables declared in the Global script can. It's described (in detail) in the BFAQ (http://americangirlscouts.org/agswiki/Scripting%2C_Code_%26_Interaction#Working_with_variables:_the_basics) (the manual version isn't quite as clear, it's true). Again, take a read through the BFAQ, see if it answers your questions before you have to ask them.
Quote
But doesn't this cause the int cutscene to always be zero when read, as it is defined at the start of the script? This is excactly my problem.
Quote
Didn't you notice the cutscene++; at the end, but if that doesn't work (because i have kind of the same problem) you could try cutscene+=1; (which probebly wouldn't work anyway)
No, WHAM is right -
ints are set to 0 at declaration unless you say otherwise, so while
cutscene ++; will set it to 1, it'll be 'destroyed' when the interaction finishes and re-declared as 0 next time the player steps onto the Region. Placing the declaration (
int cutscene;) at the top of the room script (or just anywhere before you need to use it, provided it's outside of any functions) should work for cases like this, where it only has to affect things in the one room.
Ok, I'll take some time to read the manuals.
I'll admit it, I get bored reading manuals, and I just want to get creating and learn as I go, thats why I keep asking this stuff.
Thanks again for all the help.
Quote
No, WHAM is right - ints are set to 0 at declaration unless you say otherwise, so while cutscene ++; will set it to 1, it'll be 'destroyed' when the interaction finishes and re-declared as 0 next time the player steps onto the Region. Placing the declaration (int cutscene;) at the top of the room script (or just anywhere before you need to use it, provided it's outside of any functions) should work for cases like this, where it only has to affect things in the one room.
Woops, sorry, I was thinking wrong, the variable should be put at the start of the
room script shouldn't it (now I know why my game wasn't working :P)?
Ok, call me an asshole for not getting this, but I just dont get the manual on this part at all.
I'm using the BASS base on my game, so I have an inventory already made. When I click on an item in the inventory, the cursor begomes the item, check.
How do I define how the same hotspots react to the use of this item on them?
As in: when I pick a gun from the inventory, and then click on another character, how do I get the shooting to actually happen? (No, I'm not asking about how to assign the views and loops here. Just to be clear.)
UseInventory on character/hotspot? Probably, but what kind of scripts do I define there, and how do I define which inventory item the hotspot reacts to?
BFAQ (http://americangirlscouts.org/agswiki/GUI%2C_Inventory_%26_Menu#Using_a_specific_inventory_item_to_trigger_an_action)
So:
// script for Character 2 (NPC): Use inventory on character
if (player.ActiveInventory == iGun) { // Or whatever the gun's Script-o-name is
//Do shooting stuff
cNpc.Say("You shot me, you git.");
}
Hahaha!
Thanks for the perfect readymade code! I owe you one big time!
This is no question, but I wanted those interested to see what they've helped me create here.
http://protoni.huittinen.fi/~tkahkone/Compiled.rar
The version behind the link is, as you probably guessed, far from complete, as it lacks voice acting, most sounds, most music, most rooms, and most of everything.
A friend of mine (a great drawer) has promised to help create better animations, that will be used as base for the final characters.
A proper intro will be added too, when I get there.
Thank you all, for helping me out.
Like what you have so far. good luck with the game.
Just as a side note, I'd strongly recommend against using numbered objects and characters like you've been doing:
object[0].SetView()
character[2].Walk()
etc
It's very difficult to read the code, since you don't know what object 0 is or which character 2 is. Give the objects and characters a script name in the editor, then you can do:
oDoor.SetView()
cDavid.Walk()
etc
which is much easier to read.
Quote from: Pumaman on Sat 24/03/2007 17:45:41
Just as a side note, I'd strongly recommend against using numbered objects and characters like you've been doing:
object[0].SetView()
character[2].Walk()
etc
It's very difficult to read the code, since you don't know what object 0 is or which character 2 is. Give the objects and characters a script name in the editor, then you can do:
oDoor.SetView()
cDavid.Walk()
etc
which is much easier to read.
This may be easier to read by someone else, but I'm used to using short abbreviations and numbers in the codem and having their meanings written down in a separate .txt file.
Thanks for the tip though, and I might give it a try in the next part, but this first part will be made as it has been started.
No biggie, but this is annoying me:
If you download the version I linked earlier, you'll see whats happening to the doors when you enter them. As you enter the next room, the door animates, and opens again behind you, even though you opened it earlier on the other side.
Any tips on how to get rid of this?
I simply have the doors animate when player steps into a region set in front of the door:
object[0].SetView(3);
object[0].Animate(1, 3);
Thanks'a'again!
Only moderators can delete posts, so I got rid of that one for you. In the future, if it's less that 24 hours since your last post edit it rather than double posting.
Variables will probably help here. Declare a bool in the Global Script, and make it Global (BFAQ (http://americangirlscouts.org/agswiki/Scripting%2C_Code_%26_Interaction#Working_with_variables:_the_basics)).
Then you can do something like:
object[0].SetView(3);
if (CloseDoor == false) {
object[0].Animate(1, 3);
CloseDoor = true;
}
From the test game you uploaded, it looks like you've got something that closes the door when the player steps off the region. Make that:
object[0].Animate(1, 3, eOnce, eBlock, eBackwards); // Or whatever you're using now
CloseDoor = false;
Because the bool is being set and reset for every door, one variable should be OK to use for all of them (i.e. you don't need to make a new bool for every single door).
I've tried working on the advise you gave me, Ashen, but I keep getting a parse error. This is the firs global variable I've created, so I put the whole script here, in case you can find out what it keeps complaining about. I've been changing bits and pieces of this for the last hour and something, and am gettin a little bit frustrated. ^^ This might, again, be just something I missed 'cause I lack experience, but heck!
//This is the room script for the door
#sectionstart region1_a // DO NOT EDIT OR REMOVE THIS LINE
function region1_a() {
// script for Region 1: Player walks onto region
if (doorsopen == false) {
SetObjectView(0, 3);
AnimateObject(0, 1, 3, false);
// this opens the door
//the next line has an error(?)
doorsopen == true;
}
}
#sectionend region1_a // DO NOT EDIT OR REMOVE THIS LINE
#sectionstart region1_b // DO NOT EDIT OR REMOVE THIS LINE
function region1_b() {
// script for Region 1: Player walks off region
if (doorsopen == true) {
SetObjectView(0, 4);
AnimateObject(0, 1, 3, false);
// this closes the door
doorsopen == false;
}
}
//This is the global script used to create the bool
bool doorsopen;
export doorsopen;
Elsewhere in the game I have door that are opened bu pushing a switch, and I have the doors remain open as you enter/exit the door, but now the script is on a region near the door, as you can see. This poses a totally different challenge, as in the current situation, when the player enters the next room, he is already standing on the region that opens the door, and triggering the door opening animation. I cant disable the region and activate it later, because it would not close the door then, as the player get further away from the door.
Hope you're still following me here.
Did you put
import bool doorsopen;
in the script header?
And remember that the == is only for comparing stuff, setting a variable to a certain value is done with a single =.
And you might want to indent your code to increase readability:
#sectionstart region1_a // DO NOT EDIT OR REMOVE THIS LINE
function region1_a() {
// script for Region 1: Player walks onto region
if (doorsopen == false) {
SetObjectView(0, 3);
AnimateObject(0, 1, 3, false);
// this opens the door
//the next line has an error(?)
doorsopen = true;
}
}
#sectionend region1_a // DO NOT EDIT OR REMOVE THIS LINE
#sectionstart region1_b // DO NOT EDIT OR REMOVE THIS LINE
function region1_b() {
// script for Region 1: Player walks off region
if (doorsopen == true) {
SetObjectView(0, 4);
AnimateObject(0, 1, 3, false);
// this closes the door
doorsopen = false;
}
}
I just realized another problem. In the current situation, the variable changes as the player steps OFF the region, but this also happen as he neters the door (there is another region behind the door, which causes the room change), so as the player is moved to the next room, the variable is again set so that the door opens itself, taking me back to square one.
From before the last two posts:
Also, what is the exact wording of the error message? Giving that information is a good habit to get into - but fortunately it's pretty obvious in this case, as Khris has shown.
On to new stuff:
Have the 'Room Change' region set the bool as well. That way, it'll 'reset' to closed when you step off the first region, but still run OK when you enter the next room. (You might want to include a Object.StopAnimating(); command, so the animation isn't run before you leave the room. Alternatively, let it finish before the room change, and you don't need to run the closing animation in the next room.)
EDIT:
You could also modify the 'Walks off Region' interaction to only run if the player isn't stepping onto another Region, e.g.:
function region1_b() {
// script for Region 1: Player walks off region
if (Region.GetAtRoomXY(player.x, player.y) == region[0]) {
object[0].Animate(3,3,eOnce,eNoBlock);
CloseDoor = false;
}
}
For the switch operated door, just set doorsopen in the switch interaction, when you animate the door open. It should work exactly the same on the other side (door stays open until you walk off the Region).
HAAA!!!
Thank you!!!
*Bows down to the ground and sings in joy*
You people have, once again, saved my day AND my game!
ok, this problem I cannot even describe properly. I've updated the game at http://protoni.huittinen.fi/~tkahkone/Compiled.rar and the problem can be seen in the second room you can access. If I use the elevator control there, the character walks onto the elevator, and the elevator should take him down to the lower level, BUT as you can see, tha animation is off.
the script used for interacting with the elevator control is the following, and seems to need some kind of way to define a new location for the player, that is a bit lower so that the animation gets to the right place, before running the animation.
character[0].Walk(166, 130, eBlock);
SetCharacterView(0, 16);
AnimateCharacter(0, 0, 2, false);
1. Unless you're using an AGS version earlier then 2.7 (which you're not): Stop using the old style commands (SetCharacterView, AnimateCharacter). This is nothing to do with your problem, it just bugs me :)
2. Read the manual. Character.LockViewOffset (http://www.adventuregamestudio.co.uk/manual/Character.LockViewOffset.htm) should do what you want, just set the y offset.
The "old style commands" as you called them...
I've learned most of my scripting by using the ready commands you can create through clicking 'em, and it always shows you how the same thing can be made in scripting, so I've copied that.
You're asking me to relearn this stuff AGAIN in the same month ive learned the once! This equals: sorry, but no can do, at least yet. I'll keep learning as I go, so what I find is what I learn. ^^
And the offset thing worked out nicely. Lets hope that I run out of new ideas soon, so that I wont have to ask you how to get them to work any more.
Thank you, again.
Quote from: WHAM on Mon 02/04/2007 15:42:02I've learned most of my scripting by using the ready commands you can create through clicking 'em, and it always shows you how the same thing can be made in scripting, so I've copied that.
The
has the effect part of
Character - Quick animation indeed still contains three old style commands. CJ probably focused on the
Text script equivalent code part and forgot to change it to new code.
Apart from that one single spot, every action will show proper new style commands, and you did use
character[0].Walk, so you absolutely won't have to relearn everything.
Now, see, this is why I recommend people avoid the Interaction Editor like the plague. It's crap.
In this case, learning the difference isn't that hard - open the manual and look up an old command (e.g. SetCharacterView) and it automatically redirects to the current version. And as Khris said, you're already using some of the new style commands, so there mightn't be that much to relearn.
Yeah, I've been noticing more and more of these nes style commands, and I've started digging them up (but I still wont bother going back and changing them all... nonononono!) so I'll be using purely the new ones in the future.
Easier than I first thought!
The game is getting closer and closer to being done! Only about five more rooms need to be made (easy as I have ready bases made for myself now), and some soundwork (mostly ripping off half life 2 sounds etc) and the theres the voice acting part.
I hope I'll be able to post you guys a finished version of this game in a FEW month's time, unless I get stuck somewhere in the future, but then I'll just return here to bother you guys! ;)
Looked up a few threads that seemed like they were about the same thing, found nothing I could get to work.
Deal's this. I'm using a BASS game template as the basis of my game, and as the mouse cursor is moved to the top of the screen, the inventory pops up.
Problem: I have a main menu screen, where it would be very nice if the inventory stayed hidden, no matter what.
Any ideas on how to make the inventory stop popping up? Is there some way to disable the GUI, and enable it again later?
Tampered around with "gBassinv.Visible = false; " but no effect was visible.
I guess the inventory is a "Mouse YPos" GUI, so according to the manual, setting Visible to false should stop it from popping up.
Where did you put "gBassinv.Visible = false;"?
Yeah, more information needed. What template are you using, what have you tried, what are the GUI visibility type (YPos, Popup Modal, etc)...
If you're usng the BaSS template I'm thinking of (v1.1 - I think - from Skimbleshanks/AGS Resources), it's NOT a Mouse YPos GUI, it's done with a check in rep_ex. So, adding an extra check to make sure gMainmenu.Visible == false (or whatever it's called) before turning gBassinv on should work.
Using the "Beneath a Steel Sky (template 1.1).agt" template.
GUI script:
if (interface == BASSINV)
{
if(game.num_inv_items <= game.num_inv_displayed) // show all items
{
game.top_inv_item = 0;
}
else // have more items than are displayed
{
if (button == 2) // right
{
game.top_inv_item += 5;
if(game.top_inv_item > game.num_inv_items - game.num_inv_displayed)
game.top_inv_item = game.num_inv_items - game.num_inv_displayed;
}
else if (button == 1) // left
{
game.top_inv_item -= 5;
if(game.top_inv_item < 0)
game.top_inv_item = 0;
}
}
}
With my limited ideas on how to use the "gBassinv.Visible = false;" I tried using it in the room script basically. If I'm wrong, any advise would be appreciated.
If you need any more info just ask, but be specific too. I have no idea on how to make GUI:s yet, as I only saw hope for making a game when I found an easy to use template for the GUI.
OK, that code is useless. As well as being out-of-date (due to the age of the template - interface_click has been obsolete since 2.7), it's not the right part. It deals with the controls on the GUI (the scroll arrows), not turning the GUI on or off.
That's the template I meant, though, so the answer is what I said: "it's done with a check in rep_ex." SO, open the Global Script to the repeatedly_execute function, and find a line that says:
if(mouse.y <= INVHEIGHT)
Changing that to:
if(mouse.y <= INVHEIGHT && gMainmenu.Visible == false)
(Or whatever the GUI is called) should work.
Cant test this out yet, but if I'm reading the code right here (doubtful but posible) wouldn't this make the inventory not work in the entire game, whereas I only need to turn it off in a certain room?
If I'm wrong and you have a moment to spend, would you mind clarifying a bit on what this actually does, so I can learn a bit about the GUI:s build and perhaps get some basics to make my own similiar ones in the future.
Thanks
The GUI doesn't scroll in but is turned in(visible), so I'm not sure if Ashen's code worked.
Replacing the line with
if(mouse.y <= INVHEIGHT && player.Room != X)
should, however.
Just replace the X with the room number of the main screen.
GuiOn/GuiOff is old-style code for gGuiname.Visible=true/false and will simply change the visibility of the GUI.
So provided the command is used in the right way, gGuiname.Visible=false; won't necessarily turn if off for the whole game, no.
Furthermore, putting it inside an if-condition using == instead of = will only perform a check on the current status, not change it.
Sorry, I misunderstood the question - when you said 'Main menu', I was thinking of like a 'Save/Load/Quit' one, that could be called up at anytime during the game. If it's just visible in one room, Khris' code is the way to go. My code works fine for what it was meant to do, however - stop the Inventory GUI from being visible when gMainmenu is on, but let it show at any other time. (I know it works, because coincidentally I'm working on an update to the BASS template including the 'Save/Load/Quit' GUI that's missing from the older one, and that's pretty much the code I'm using.)
HAA!!!
Khris, you have just made my day!
Am I correct in believing that adding a
if(mouse.y <= INVHEIGHT && player.Room != X or player.Room != Y)
would make it possible to add more rooms to the list? This way Icould be sure that the inventory wont pop out accidentally during the game's intro or outro.
Jup, that's it.
The exact syntax would be:
if (mouse.y <= INVHEIGHT && player.Room != X && player.Room != Y)
Though I'd code it like this:
int ro=player.Room;
if (mouse.y <= INVHEIGHT && !(ro==4 || ro==5 || ro==7))
- !(..) means NOT ..
- or is done by ||
Quote from: KhrisMUC on Thu 19/04/2007 15:04:02
- or is done by ||
I'll have to remember that. My most basic programming goes back to Pascal, that I think used "OR", and that's stuck on me. I'll have to dig up the proper java counterparts somewhere, and print them out.
Although it probably doesn't matter, I'd rather use AGS's manual for reference ;)
http://www.adventuregamestudio.co.uk/manual/Operators.htm
Quote from: KhrisMUC on Thu 19/04/2007 21:48:34
Although it probably doesn't matter, I'd rather use AGS's manual for reference ;)
http://www.adventuregamestudio.co.uk/manual/Operators.htm
By the way: Have I been correct in my beliefs that AGS uses Java as its script language. I have a shallow experience in Java, and AGS script seems (at least for its "if" sentences) to be the same. Or are there differences? Should I keep studying Java and AGS separate, or combine them?
Study Java to program Java, study AGS to script something in AGS ;)
They are very similar and AGS's scripting language is heavily based on Java, at least syntax-wise. But there are of course many restrictions to AGS's language, as in it's meant to script adventure events only.
There's e.g. no "new" keyword in AGS.
Edit: Added emphasis.
@dkh: Compared to languages like BASIC, AGS & Java are practically identical, don't you think?
Er, I don't know much Java, but I program in C++, and AGS-script is very similar to C++ and much less to Java, in fact I wouldn't call Java and AGS-script similar at all.
I return once more to siphon your endless wisdom!
I have conversations that take place through a radio, that is located on the players (cEgo) person.
Is there a way to have messages appear above the player character, as if he was talking, except that the text colour is different and the character does not enter the talking view? (There's voices inside his head!)
Thank you.
Use an invisible character which is the same height as the player's and let him do the talking.
Quote from: KhrisMUC on Wed 02/05/2007 17:51:26
Use an invisible character which is the same height as the player's and let him do the talking.
Ummmm... Have this invisible character appear at the players coordinates and then make the talking happen?
Invisible character? Make a character that's only view has only one colour: transparent?
Same coordinates? Wont the game not allow the two characters stand on the same coordinates?
Yes. Call "cRadio.ChangeRoom(player.Room, player.x, player.y);" before starting the dialog / calling the Say commands.
Just use cEgo's view(s) for the char, then put "cRadio.Transparency=100;" in game_start.
It will. This is only an issue if chars walk into each other and even that can be made work by setting the Solid property of one of the chars to false.
WORKS!!! Thank Khris!
Just going to throw a quick question here.
Is there a way to give an inventory item a default message, that would be said by the cEgo every time that item was used on something that has not been set to react to that item. For example: I have a gun, that when used on a certain hotspot, triggers a cutscene. If it is used on a pair of boot lying on the floor, or anything else for that matter, the character says "No use".
The way I see it now, is to give each and every hotspot a way of reacting to that item, by making cEgo say this message. Troublesome...
Sure just look up unhandled_event (http://www.adventuregamestudio.co.uk/manual/TextScriptEvents.htm) in the manual. You see that you want to use type 3, but you may also want to distinguish at least between characters and objects/hotspots in the responses ("I see no reason to shoot at that.", "No, I'm not a killer!").
Check the player.ActiveInventory property to distinguish between different items.
This can be done by using unhandled_event.
Add it to the global script:
function unhandled_event (int what, int type) {
if (type==3) { // use inv on
InventoryItem*i=player.ActiveInventory;
player.Say(i.GetPropertyText("unhandled");
}
}
In the Custom properties editor, add a new string property with name "unhandled" and a default value of, say, "That doesn't work."
Now enter an appropriate message for every inv item.
This will work for every hotspot/char/object... with a blank "use inv on ..." interaction.
If there are actions in "use inv on ..." defined:
if (player.ActiveInventory==iKey) { // intended item(s)
...
}
else unhandled_event(1, 3);
If this doesn't work, try I'm- and exporting unhandled_event.
If it still doesn't work, add this below the declaration of unhandled_event:
function unhandled() {
unhandled_event(1, 3);
}
export unhandled;
and import it in the script header, then call unhandled(); at the end of the interaction.
Hey guys! I'm back! AGAIN!!!
The following code is my shooting script for the game, but it has one tiny problem. Apparently due to the "cEgo.ChangeView(1);" at the end, the cEgo's shooting animation is not run properly, as only the first frame of it is run. Any ideas on how to solve this? I recon that having the animation be a blocking one would help, but can I even have two animation running at the same time, that are both blocking?
if (player.ActiveInventory == igun40 || player.ActiveInventory == igun30 || player.ActiveInventory == igun20 || player.ActiveInventory == igun10) {
if (player.x < cAi3.x) {
cEgo.Animate(8, 5, eOnce, eNoBlock);
cAi3.Animate(8, 5, eOnce, eNoBlock);
}
else if (player.x > cAi3.x) {
cEgo.Animate(9, 5, eOnce, eNoBlock);
cAi3.Animate(9, 5, eOnce, eNoBlock);
}
}
cEgo.ChangeView(1);
Thanks...
Change both Ai3's anims to blocking.
You can't run two blocking anims at the same time, but if you run the first non-blocking and the second one blocking, they will run blocking simultaneously.
With your current code, AGS only gets to the first frame, because Ego's view is changed immediately afterwards.
Ahhh... Thanks!
I've never been that good with figuring out how these things work, but this helped alot. I thought that having the animation block would cause the earlier activated animations to also cease.
Quote from: KhrisMUC on Fri 04/05/2007 22:13:03
This can be done by using unhandled_event.
Add it to the global script:
function unhandled_event (int what, int type) {
if (type==3) { // use inv on
InventoryItem*i=player.ActiveInventory;
player.Say(i.GetPropertyText("unhandled");
}
}
In the Custom properties editor, add a new string property with name "unhandled" and a default value of, say, "That doesn't work."
Now enter an appropriate message for every inv item.
This will work for every hotspot/char/object... with a blank "use inv on ..." interaction.
If there are actions in "use inv on ..." defined:
if (player.ActiveInventory==iKey) { // intended item(s)
...
}
else unhandled_event(1, 3);
If this doesn't work, try I'm- and exporting unhandled_event.
If it still doesn't work, add this below the declaration of unhandled_event:
function unhandled() {
unhandled_event(1, 3);
}
export unhandled;
and import it in the script header, then call unhandled(); at the end of the interaction.
I've tried this quite a few times now, altering it and trying to get it to work, and keep getting an error:
"We're sorry, the AGS editor has encountered a serious error and must shut down...
(Exception 0.0000000 at EIP=0x0000000,
AGSEDIT v2.72.652, SIP=26)
Ideas on the reason? This happen when I put KhrisMUC's code into the global script and test the game. Something about is either wrong or then there's a problemn with something else.
I'm not quite sure, but maybe declaration of pointer variable in a function is not supported.
Try moving the Inventory* declaration line of unhandled_event() out of the function to the top of the script, or try:
function unhandled_event (int what, int type) {
if (type==3) { // use inv on
player.Say(player.ActiveInventory.GetPropertyText("unhandled");
}
}
Ok... I dont know what I've changed, but at the moment, both:
// main global script file
function unhandled_event (int what, int type) {
if (type==3) { // use inv on
InventoryItem*i=player.ActiveInventory;
player.Say(i.GetPropertyText("unhandled");
}
}
/*************************************************************\
GLOBAL VARIABLES
\*************************************************************/
and:
// main global script file
function unhandled_event (int what, int type) {
if (type==3) { // use inv on
player.Say(player.ActiveInventory.GetPropertyText("unhandled");
}
}
/*************************************************************\
GLOBAL VARIABLES
\*************************************************************/
Return a "Runtime error: Umexpected eof". I'm not even sure if it matters if I put this script in a certain area of the global script or not? Does it? I've been trying to put it at the very beginning or the very end.
player.Say(i.GetPropertyText("unhandled") );
You're missing that closing bracket.
However, it's quite bad that this causes the editor to crash.
AFAIK, declaring pointers in functions works fine - it always has for me, anyway.
In addition to the missing ')' Pumaman noticed, everyone in this thread apparently needs to read the manual ;) - the function is called GetTextProperty, not GetPropertyText. (At least, after V2.7 it is.)
However, even with the wrong command and the missing ')' I don't get the original crash, just 'unexpected eof' and 'undefined token'. Either there was something else that you've fixed without realising, or AGS was just having a bad day when it threw that one out.
Well... fcuk!!! FCUK!!!
The closing bracket and the wrong order of words in GetTextProperty have been causing the problem! I'm just too friggin BLIND to spot these things. *bangs head to the wall in frustration*
Thanks for pointing this out people, I'll be trying this out today but it seems to be working. Ill modify the results here in an hour or two.
EDIT: Works like a charm now! WOOHOOO!!!
I seem to be unable to find a following anywhere:
How do I remove an inventory item from the player? I can find a dozen tips on adding and using the items but nothing on removing them. Perhaps I just use the wrong words for the search but... blargh...
Character.LoseInventory (http://www.adventuregamestudio.co.uk/manual/Character.LoseInventory.htm), or even directly modifying Character.InventoryQuantity (http://www.adventuregamestudio.co.uk/manual/Character.InventoryQuantity.htm) (e.g. player.InventoryQuantitiy[iKey.ID] --;), though player.LoseInventory is best unless you need to remove multiple instances of an item. How did you not see them in the manual? It seems like a lot of your recent questions here could've been solved by checking the manual, or (as with the missing '(') double checking your code.
EDIT:
As is the case with most related commands, LoseInventory is cross-linked with AddInventory. No need for searching.
"Lose"...
I was dilligently looking for something along the lines of "RemoveInventory" as opposed to the "AddInventry"... Thanks Ashen... And sorry. I did look at the manual but as I used ctrl+f to scan through it with any search words I could come up with, I failed to spot this.
The good news is that I wont be asking the same thing twice, ever! Promise!
Project again underway. New question has arisen.
My game is being quite heavy on different actions taking place as the main character walk onto a certain region (doors opening etc) but this has caused a veeery annoying problem.
If I anter a room and click on a hotspot that has a walk to point, and the character goes to this walk to point, he doesn't trigger any regions. This causes doors animating opening twice as they never closed and such. Is there a way to fix this?
Thanks again.
It seems like the walk-to point may be calling a blocking function, which would definately cause some problems with walking on the region.
I have 2 Possible solutions (not sure which is best):
- Add something in the Always_Executes function that checks to see if the player is standing on a region in the rooms which give you trouble.
- Remove the walk-to points and use character.Walk() instead with eNoBlock on (you may need to code around some things so that the eNoBlock doesn't screw up your list of actions.
I'm not sure if either of those would work. I'm inclined to think that using the Always_executes function like this would cause some serious lag on slower machines, and I'm not sure if using eNoBlock would be feasible. But that's what I've got, someone please correct me if I'm wrong.
Yeah... I was thinking about abandoning walk to points and using cEgo.Walk...
I just asked if anyone knew a better way so I wouldn't have to remove them all and replace them with the walking commands.
Thanks anyway.
I'm 90% certain this question has been asked before, but I can't find the damn thread...
As I remember it, the answers boiled down to what Recluse said anyway, but if you can find it, there might be some other options for you.
Quote from: WHAM on Sun 05/08/2007 08:58:47
Yeah... I was thinking about abandoning walk to points and using cEgo.Walk...
Personally, I never trust the Interaction editor, or any of AGS's "graphical no-scripting needed functions". I'll always rely on my code to get things done, that way I have complete control.
Hi! Bringing this thread back from the dead, as I'm back on the project and in need of help once again!
I worked a good while, making all kinds of changes to my game and as I tried to test-run it, I got the following error:
_AutoGenerated.ash(59): Error (line 59): macro 'ELLIE' already defined
in the Output window.
I have NO idea what could've caused this and I've been triyng to delete my most recent additions to the room scripts I was making, but with no effect. Any good ideas are welcome!
EDIT: oh! And ellie is one of the characters in the game, referred to with cEllie. Although that name is not supposed to be used in any of the games script at the moment, making this even more a mystery to me.
Afaik, AGS generates that script immediately before compiling the game, and naming your character cEllie will add the line "#define ELLIE 24" to that script.
Try renaming the char and/or look for anything else with that script name, maybe a view?
Found it... The Views and characters had the same name... Didn't pop into my little mind that they cannot have the same name! >.<
The game is nearing completion at last, only a month or so until deadline! I might be popping here for more help in that time...
Here's a codemonster that is giving me a headache. The problem is that of the following piece of code, only certain bits and pieces are run, while the rest is not, and I cannot find a reason why! Further explanation in comments of the code:
function room_AfterFadeIn()
{
if (GetGlobalInt(1) == 10) {
// Player ends his move on region 1 so we disable that for the time being
DisableRegion(1);
cDude.FollowCharacter(null);
// Move the player to the region
cEgo.Walk(273, 143, eBlock, eWalkableAreas);
// The walkable area is not removed!
RemoveWalkableArea(2);
//From here on out, the script plays out correctly, until...
SetObjectView(0, 5);
AnimateObject(0, 0, 5, false);
Wait(20);
cEgo.Walk(296, 139, eBlock, eWalkableAreas);
cEgo.ChangeView(15);
Wait(20);
AnimateObject(0, 1, 5, false);
Wait(40);
ObjectOn(3);
Wait(10);
ObjectOn(4);
Wait(30);
ObjectOff(2);
Wait(20);
ObjectOn(5);
// ... here! The object 5 won't move!
MoveObject(5, 166, 72, 6);
cDude.ChangeRoom(0);
Wait(40);
cEgo.ChangeView(1);
SetGlobalInt(1, 12);
// Restore region 1 so it works again the next time player enters the room
EnableRegion(1);
// In the end, the player ends in room 666
cEgo.ChangeRoom(666, 105, 142);
}
}
EDIT: BAH! I've been using old and non working commands in my script again! This problem solved itself after a good night's sleep and some newer commands (oObject5.Move(138, 98, 6, eBlock, eAnywhere)). Sorry for wasting your time.
Is there a way to SILENCE music in AGS games without stopping it and having it restart again when you restore it. I need to have a moment of silence in my game, but my music track is almost 30 minutes long and I dont want to have to restart it...
Also: can you play another music on top of the first, or do I have to have the second music simply as a SOUND file instead?
SetMusicMasterVolume(0);
You have to use a sound.
So I thought. Thanks! I hereby promise that I wont be bothering you again in a long time, as my first game is finelly about to be released within two weeks from now!
You guys have been a great help! Thank you all.
I'm having a pretty big problem here, and was hoping that someone might have an idea on how to solve it:
I have about 700 character.Say commands throughtout my game. Three different characters, all character.Say commands have a line of voice acting(mp3) attached to them.
The problem is this: Some lines of voice acting are halted right at the end, so that the timer never kicks in and automatically ends the say command. The voice just stops at the end and the text floating above the character's head stay's there until the player klicks on presses a key.
Could this be because of overusing repeatedly execute? It's the only thing that came to my mind...
The problem only presents itself with certain character.Say commands and always in the same way. The mp3 files seem to be ok and run normally in all other programs (winamp, windows media player, audacity).
A new game in the making, a new issue to tackle:
If you've played Resident evil 4, you will remember the active cutscenes in the game. I'm looking to replicate these in an AGS game.
The idea is as follows: A cutscene runs in the game, then is halted in a certain phase and the player is prompted for input. If the user gives the correct input quickly enough, the game responds, if not, the game responds differently (for example, the player was too slow to dodge a bullet, gets hit and dies instantly).
HOW can you make this? How do I stop a cutscene and wait for the player to react, how do I create a timer like this? If someone could give me a basic idea to build on, I'd be ever grateful.
// cutscene code
int seconds = 2; // two seconds to react
Overlay*o = Overlay.CreateTextual(..., "PRESS SPACE!");
int timer;
int button;
while(timer<seconds*GetGameSpeed()) {
if (IsKeyPressed(' ')) button = 1;
Wait(1);
timer++;
}
o.Remove();
if (button) {
// continue cutscene
}
else {
// kill player
}
Wow... I mean just... wow... This is why I love this forum...
Thanks Khris, I'll be experimenting when I get home from work in a few hours...
Wow...
...damn!...
Bringing this thread up again, as now that I've actually started to implement the script Khris gave me in his last post (Christ! It's been MONTHS!), I realized that the script is not quite cutting it due to the following reason: you can only have it set on one second intervals, instead of giving it the amount of time for the player to react in either fractions of a second, or in game loops.
Any good ideas on how to remedy this, all I've gotten in my attempts has been a bunch of "cannot convert to int" etc. errors...
Thanks again in advance!
the
while(timer<seconds*GetGameSpeed())
part is converting game loops to seconds.
just replace that while statement with the number of game loops you want to wait.
Quote from: Calin Leafshade on Fri 01/01/2010 22:06:21
the
while(timer<seconds*GetGameSpeed())
part is converting game loops to seconds.
just replace that while statement with the number of game loops you want to wait.
Wait, what? Can you give me a code example where the game waits for, lets say 20 game loops (1/2 of a second), please? I'm afraid I didn't quite understand what you just said... :-\
Quote from: WHAM on Fri 01/01/2010 23:01:07
Quote from: Calin Leafshade on Fri 01/01/2010 22:06:21
the
while(timer<seconds*GetGameSpeed())
part is converting game loops to seconds.
just replace that while statement with the number of game loops you want to wait.
Wait, what? Can you give me a code example where the game waits for, lets say 20 game loops (1/2 of a second), please? I'm afraid I didn't quite understand what you just said... :-\
while(timer<40) //If 40 is the time you want to wait for input.
You said you want for example to dodge a bullet in a certain time period. That time period is represented by the number 40. Ideally you can have a global variable instead of 40 and adjust time period for every alike scene.
Quote from: Dualnames on Fri 01/01/2010 23:08:03
Quote from: WHAM on Fri 01/01/2010 23:01:07
Quote from: Calin Leafshade on Fri 01/01/2010 22:06:21
the
while(timer<seconds*GetGameSpeed())
part is converting game loops to seconds.
just replace that while statement with the number of game loops you want to wait.
Wait, what? Can you give me a code example where the game waits for, lets say 20 game loops (1/2 of a second), please? I'm afraid I didn't quite understand what you just said... :-\
while(timer<40) //If 40 is the time you want to wait for input.
Yopu said you want for example to doge a bullet in a certain time period. That time period is represented by the number 40. Ideally you can have a global variable instead of 40 and adjust time period for every alike scene.
Aaaaaa! Now that I see it written, I get it. Thanks a lot to you both!