'Hooked on Scripting' didn't work well for me ...

For Descent, Descent II and Descent3 level editing and modification assistance.
Post Reply
Arbitar
DBB Ace
DBB Ace
Posts: 186
Joined: Sun Apr 04, 2004 1:49 am

'Hooked on Scripting' didn't work well for me ...

Post by Arbitar »

OK, I've been trying to figure this out for a while now, and I just can't get it ...
OK, here's the problem...
I have something that is moving, and you need to shoot. OK. I got that in and everyhting. What's supposed to happen is, when you shoot it, I want the score to go up one point, and a message to be displayed (which I already took care of). So far, I'm stumped ... :(
Any help would be greatly appreciated.
This is what I have for it so far:


Script 009: Target Score
---Owner: Target (Object)
---Event: Collided (with IT)
---If the following condition is met:
------(IT is a player weapon) is TRUE
---------Bool: It is a player weapon
------------Object: IT
---------Operation is TRUE
---Then preform the following actions:
------Show HUD message TargetHit
---------Message: TargetHit



Thanks,
Arbitar
User avatar
Kyouryuu
DBB Alumni
DBB Alumni
Posts: 5775
Joined: Fri Apr 30, 1999 2:01 am
Location: Isla Nublar
Contact:

Post by Kyouryuu »

I don't think you can change the player score in DALLAS.
Arbitar
DBB Ace
DBB Ace
Posts: 186
Joined: Sun Apr 04, 2004 1:49 am

Post by Arbitar »

Dang ... OK, Thanks. Do you think theres anything that I might be able to use as a score counter in replacement of 'the real one'? I tried adding objects to the inventory titled 'Score', and then for each one a new one would be added, but that didnt work.
User avatar
Interceptor6
DBB Ace
DBB Ace
Posts: 138
Joined: Sat Mar 01, 2003 3:01 am
Location: baton rouge, LA, USA

Post by Interceptor6 »

Just increment a Uservar when you hit the object. I don't think there's a way you can display it on screen though. But inventory items probably won't work.
User avatar
SuperSheep
DBB Benefactor
DBB Benefactor
Posts: 935
Joined: Sun Jun 03, 2001 2:01 am
Location: Illinois

Post by SuperSheep »

When I wrote Asteroids for D3, I simply used the score stored in the GAM to give the player points. Since you can create objects in scripting as well, all one would need to do is create a dummy object with the score you want to add to the player, destroy the object with the player being the "killer" and that should do the trick.

It's been a while since I looked at the source from Asteroids, so if you want me to give you the exact functions you'll need to call, let me know cause I'll have to dig 'em up then. :)
Arbitar
DBB Ace
DBB Ace
Posts: 186
Joined: Sun Apr 04, 2004 1:49 am

Post by Arbitar »

I hadn't thought of that SuperSheep!
Thanks! I'll try that :D
Arbitar
DBB Ace
DBB Ace
Posts: 186
Joined: Sun Apr 04, 2004 1:49 am

Post by Arbitar »

Well ... it kinda worked and ... kinda didnt.
The kinda did part is ... i got a dummy object and the kinda didnt part is that I could figure out how to create an object in scripting, or set the player as killer when destroyed. I know, I probly sound like some idiot asking how to do things like this that are probly so simple. :P
I'll let you know if I get it :lol: I'm sure I will eventually
User avatar
SuperSheep
DBB Benefactor
DBB Benefactor
Posts: 935
Joined: Sun Jun 03, 2001 2:01 am
Location: Illinois

Post by SuperSheep »

There is a section in the cpp file near the top that is for custom scripts. It looks like this...

Code: Select all

// ===============================================================
// Start of Custom Script Block - DO NOT EDIT ANYTHING BEFORE THIS
// ===============================================================
/**{CUSTOM_SCRIPT_BLOCK_START}** DO NOT EDIT! **/
 
// Enter your custom script code here
 
/**{CUSTOM_SCRIPT_BLOCK_END}**** DO NOT EDIT! **/
// ============================================================
// End of Custom Script Block - DO NOT EDIT ANYTHING AFTER THIS
// ============================================================
It is in this section that you can create your own custom script to perform whatever actions you desire and then call that function in dallas.
Unfortunately, there was a great site that had some examples but it is now gone. I will repost the text here so you can examine it.
Tutorial 3
October 4, 1999

Subject:
--------
Creating Custom Actions/Queries For DALLAS

Synopsis:
---------
In this tutorial you will find out how to create custom queries and actions
for DALLAS. This allows you to addon to DALLAS's functionality, via some
OSIRIS scripting. The example in this tutorial will create a new Query function
that will allow you to check certain flags of a room to see if they are set.
This can be very useful, if you want to make your level actually respond to
say Entropy, in which the room flags change depending on what kind of room
it is, and which team owns the room.

Creating A Custom Action/Query:
-------------------------------
When DALLAS loads up it does two things. It first opens dallasfuncs.cpp from
your D3-SDK/osiris directory. It parses it for all the actions/queries/flags/etc
that you see in DALLAS when you use it. It then opens up the script associated
with your level. This file has the same name as your level, but has a .cpp file
extension, and it is also located in your D3-SDK/osiris directory. But there
is a neat little sub-step involved in this step, that allows you to add-on to
DALLAS. While DALLAS is parsing (reading and interpreting) your level script
file, it looks for a certain block of code. It treats this block of code as
an extension to dallasfuncs.cpp. By placing dallasfunc.cpp-like functions, etc.
you can make some custom queries and actions, for your level only.

For a couple examples of this use, numerous levels shipped with Descent 3 used
custom actions/queries. For instance, Level 5, with displaying the Reactor
Life Meters and countdown times, is done in a custom script block. The entire
puzzle sequence of Level 6, involving the priest icon (where you travel through
the columns) is done in a mix of custom actions/queries and regular C functions
(called by the custom queries/actions).

There are two things you have to know, on creating custom actions/queries. One
is the formal format of the function headers that DALLAS parses. You must get this
correct, in order for DALLAS to correctly parse your function. The other is
how to code with OSIRIS (yes, it's really C++, but you need to learn how to call
the functions located in osiris_import.h to interact with Descent 3). I will
briefly go over the first prerequisite. The second one (knowing OSIRIS) is left
as an excerise as the user. For both, I suggest taking a gander through
dallasfuncs.cpp and see how we at Outrage wrote the functions. It shouldn't be
too hard to figure out from there (assuming you know C/C++).

DALLAS Function Headers:
------------------------

When DALLAS parses dallasfuncs.cpp and your level script, it looks for and parses
a certain format of a header, for information it needs for use. Below is a list
of what DALLAS will look for, and how it will read it. For all below, I recommend
refering to dallasfuncs.cpp to see them in use. It maybe just easiest to copy/paste
from dallasfuncs.cpp and make whatever changes you need.

Rule #1: All function/type headers must be in comment. This isn't for DALLAS
but for your compiler. It will generate plenty of errors if you forget to
comment the headers. And you must use the /* */ comment style and not the
// comment style. This is because, by using // you add characters to the
beginning of each line that DALLAS can't understand.

Rule #2: These are the variable types that DALLAS understands and knows how to
work with. Some of these match right up with C/C++ variable types, and the others
are Descent 3 specific. The reason you need to use these types is because DALLAS
preforms a lot of type checking (among other things) that requires to know exactly
what it is passing in.

Dallas types:
------------
ID Name How passed
-- ---- ----------
o object object handle
d door handle of door object
r room integer room number
t trigger integer trigger number
i int integer
b bool unsigned byte/bool
f float single-precision float (4 bytes)
p percentage single-precision float in range 0.0 - 1.0
v vector pointer to triplet of floats
s string pointer to null-terminated string
e enum integer (DALLAS defined enumeration)
g flag integer (a combination of flags, DALLAS defined)
a name a specific (non-localizable) name, as of a matcen. Does not appear in the message file.
n sound sound name
h path integer path number
m matcen integer matcen numer
l level goal integer level goal number
z streaming audio pointer to null-terminated name of audio file


Rule #3: Enumerated types are just a way of assigning a string to a number value.
In Dallas you can define your own enumerations (which are recognized by the DALLAS
type e). To define an enumerated type, you must begin the block with the following:

$$ENUM <Enum Name>

where <Enum Name> is the name of the Enumeration. This is important because when
you write action/queries that use this enum type as a parameter, you must specify
this name (so DALLAS knows what enum type you are talking about). What follows
next is a list of all your enums in the format:

<value>:<name>

where <value> is the integer value of the string, and <name> is the text name
of the value.

Finally, the block is ended with the:

$$END

As an example of an Enumerated type, the following is the enumerated type used
for spew types, that you can select when creating a spew:

$$ENUM SpewType
0:Explosion0
1:Explosion1
2:Explosion2
3:Explosion3
4:Explosion4
5:Explosion5
6:Explosion6
7:Grey Smoke
8:Black Smoke
15:Red Spark
16:Blue Spark
23:Napalm
28:Raindrop
35:Corona0
36:Corona1
37:Corona2
38:Corona3
39:Snowflake
41:Blue Fire
$$END

Rule #4: Flags (DALLAS type g) are very similar to enumerated types. The
difference is that multiple flags can be passed in one value (for this reason,
each individual flag is a power of 2, which maps to a specific bit in the 32 bit
integer). Enumerated types can only be one value, but flags can be multiple
values.

To begin a flag group, you start with:

$$FLAG <Flag Group Name>

Where <Flag Group Name> is the name of the group of flags that are following. Like
enumerated types, this value is important when it comes to creating a query or
an action, as this is how you tell DALLAS what group of flags to use for the
parameter.

What follows is a list of all the flags and their values for the group. They
are in the format of:

<value>:<name>

Where <value> is a decimal integer value of the specific flag, and <name> is the
text name of this flag.

Finally, the block is finished off with:

$$END

What follows is an example of a flag group for DALLAS. These are the individual
physics flags that are used in various actions/queries.


$$FLAG PhysicsFlags
128:Gravity
2048:Fixed Velocity
32768:Reverse Gravity
65536:No Collide
2097152:Ignore Concussive Force
8388608:Lock X
16777216:Lock Y
33554432:Lock Z
$$END


Rule #5: Probably the most important/used header is the actual function header
for an action or a query. DALLAS uses this information to determine which
menu it belongs in, on the action/query menu. It uses it to determine if it is
an action or a query. It also uses it to know what kind of parameters (and in
what order) it expects, and it also gives it descriptive information about the
function.

The first line determines whether the function is going to be an action or a
query. An action function returns void, and is used to do something. Query
functions are to return a value, and can optionally do something like an action
function. Action functions begin with

$$ACTION

while query functions begin with

$$QUERY

The next line tells DALLAS what category this function belongs in. Which is one
of the following values:
Objects,Players,Doors,Rooms,Triggers,Spew,Weather,AI,Sound && Music,Timer,
Level Goals,Mission,Math,User Vars,Misc,Scripts,Cinematics,Custom

The next line performs multiple actions. Firstly, it is the textual information
that you will see in DALLAS when selecting the action/query. It also tells DALLAS
which variable types will be passed as parameters (and in the case of a query
function, it tells DALLAS what kind of value it will return) and in what
order they will be in. DALLAS parses the line as a regular line of text, however,
when it comes across a bracket set [], what is inside the brackets, describes
a variable that will be passed in as a parameter. Inside the brackets, the format
is as followed:
[<DALLAS variable type>:<Name>]
Where <DALLAS variable type> is one of the above listed types of variables DALLAS
knows about. And <Name> is the name DALLAS will display for the user. But in the
case of Enumerated types and flags, this is what group of enums/flags it should
expect.
For query functions, this line begins with a DALLAS variable type, followed by
a colon, to represent what value this function returns.

The next line is the name of the function DALLAS should call. This is typically
the name of the function that follows the comment block.

The remaining lines (as many as you want), is just for description purposes.
Typically you will want to describe the action/query here, and what it
expects as parameters (and maybe legal/illegal values for them).

Finally, the block is ended with:

$$END


Putting It All Together:
------------------------

So, you read the above and you understand it all! (It's easier than it sounds,
just look through dallasfuncs.cpp). Now, where do you put all this stuff. Simple,
just open up the .cpp file for your level script and look for the following
block of text:

// ===============================================================
// Start of Custom Script Block - DO NOT EDIT ANYTHING BEFORE THIS
// ===============================================================
/**{CUSTOM_SCRIPT_BLOCK_START}** DO NOT EDIT! **/


/**{CUSTOM_SCRIPT_BLOCK_END}**** DO NOT EDIT! **/
// ============================================================
// End of Custom Script Block - DO NOT EDIT ANYTHING AFTER THIS
// ============================================================

You'll want to put all your code, declarations, variables, etc. between these
two blocks. If you put anything outside of them, IT WILL BE DELETED the next
time the level script is saved in DALLAS. DALLAS will only preserve what
is in between these two blocks.


An Example:
-----------

The following is a block of custom code, along with the needed headers. It is
a query to find out if a room has certain flags set for it. I also have to
create a new type of flag group, which is all the values of the room flags. I got
these values from room_external.h in the D3-SDK/include directory.

Code: Select all

// ===============================================================
// Start of Custom Script Block - DO NOT EDIT ANYTHING BEFORE THIS
// ===============================================================
/**{CUSTOM_SCRIPT_BLOCK_START}** DO NOT EDIT! **/

/*
$$FLAG RoomFlags
1:Fuel Center
2:Door Here
4:Room Is External
8:Room Is Goal 1
16:Room Is Goal 2
128:Room Is Goal 3
256:Room Is Goal 4
512:Room Is Fogged
1024:Room Has S1 Set
2048:Room Has S2 Set
4096:Room Has S3 Set
8192:Room Has S4 Set
16384:Room Has S5 Set
32768:Room Has S6 Set
134217728:Room Has A WayPoint
268435456:Room Is A Secret Room
$$END
*/

/*
$$QUERY
Rooms
b:[r:Room] has Flags [g:RoomFlags=0] Set
qRoomHasFlagsSet

Parameters:
	Room: The room whose flags you want to check
	RoomFlags: Which flags you want to check (all flags must
	           be set in order for this function to return
			   true.  If one of the flags is not set, then
			   the value returned is false).
$$END
*/
bool qRoomHasFlagsSet(int Room,int RoomFlags)
{	
	char used;
	int flags;

	Room_Value(Room,VF_GET,RMV_C_USED,&used);
	if(!used)
		return false;

	Room_Value(Room,VF_GET,RMV_I_FLAGS,&flags);

	if(flags&RoomFlags)
		return true;

	return false;
}


/**{CUSTOM_SCRIPT_BLOCK_END}**** DO NOT EDIT! **/
// ============================================================
// End of Custom Script Block - DO NOT EDIT ANYTHING AFTER THIS
// ============================================================
The function to create an object is...

Code: Select all

Obj_Create(ubyte type,ushort id,int roomnum,
 vector *pos,const matrix *orient=NULL,
 int parent_handle=OBJECT_HANDLE_NONE,
 vector *initial_velocity=NULL);
The function to destroy an object is...

Code: Select all

Obj_Kill(int handle,int killer_handle,
 float damage,int flags,float min_time,float max_time);
Both can be found in osiris_import.h

The killer_handle would be the players handle.

So basically you can create a function that creates your dummy object with the score you specify, then kill it immediately afterwards with the player as the assigned killer.

I wish I could be of more help but its been ages since I've done level scripting.
Arbitar
DBB Ace
DBB Ace
Posts: 186
Joined: Sun Apr 04, 2004 1:49 am

Post by Arbitar »

:|
Woah...
Ok. :D Awesome. Thanks SuperSheep!
I never thought it possible to create objects in DALLAS. :oops:
I was wrong. :D
Thanks!
yfmain
DBB Ace
DBB Ace
Posts: 22
Joined: Tue Sep 28, 2004 9:14 am
Location: Dundee, UK

Post by yfmain »

Interceptor6 wrote:Just increment a Uservar when you hit the object. I don't think there's a way you can display it on screen though.
you can display a Uservar as HUD msg, by using functions like "Shows a HUD message [message][integer]". be sure you have "%d" in your message string.
yfmain
DBB Ace
DBB Ace
Posts: 22
Joined: Tue Sep 28, 2004 9:14 am
Location: Dundee, UK

Post by yfmain »

unfortunately, i could not find a function can get player's name in osiris_import.h.
I wanna record and display pilot names, but havenot got a clue yet.
Post Reply