Notecard
Notecard 是 Second Life 里的的其中一种 inventory item ( 通常是 a text file), 每个 notecard 都有一个 key ,通过下列步骤你可以获得该 notecard 的 key : right-clicking a notecard and selecting "Copy UUID to clipboard".
Notecards 能够包含 any type and number of inventory items embedded into the text (objects, clothes, textures, other notecards, landmarks, etc.).
Notecards are limited in size to 64KiB of text.
Notecards can be read using
llGetNotecardLine() unless they contain any inventory items as described above. Notecard 涉及到的 Functions and Events 有:
Functions
|
Function
|
Description
|
|
llGetNotecardLine
|
读取所指定的 notecard 里的某一行的 data 。当返回 data 时会 trigger dataserver event.
|
|
llGetNumberOfNotecardLines
|
获取所指定的 notecard 包含的行数。返回行数时会 trigger dataserver event.
|
|
llGiveInventory
|
把一个 notecard 送给 a user 。执行该方法时,该 notecard 的内容就会在一个 popup notecard window 里显示出来,该 user 可以选择是 keep 还是 discard 该 notecard 。这也是一个常用的显示 text 的方法。
|
Events
|
Event
|
Description
|
|
changed
|
当 1 个 notecard 被添加到 object ,或从 object 里删除,或对 object 里的 notecard 进行了修改,都会 trigger 该 event 。 当然其他 inventory item 发生增删改的情况也会 trigger 该 event ,而不仅仅是 for notecard 。
|
|
dataserver
|
Triggered when calls to llGetNotecardLine or llGetNumberOfNotecardLines returns data. 当然还有其他 request data 返回时也会 trigger 该 event ,我们后面会讲解
|
相关 Function 的详细讲解
string llGetInventoryName(integer type, integer number)
获取某个 inventory 类型的所指定的 index 的 inventory item 。 Item index 是从 0 开始的。如果所指定的 inventory 类型没有任何的 item ,就返回一个 empty string 。 如果你想要先 check 该 inventory type 里是否有 item ,你需要使用 llGetInventoryType
!!请注意 : inventory item 的排序是根据 name 的字母大小来排 下面的 constants 用来指定 inventory type :
|
Constant
|
Value
|
Look At
|
Hex
|
|
INVENTORY_ALL
|
-1
|
all inventory items
|
|
|
INVENTORY_ANIMATION
|
20
|
animations
|
0x14
|
|
INVENTORY_BODYPART
|
13
|
body parts
|
0x0D
|
|
INVENTORY_CLOTHING
|
5
|
clothing
|
0x05
|
|
INVENTORY_GESTURE
|
21
|
gestures
|
0x15
|
|
INVENTORY_LANDMARK
|
3
|
landmarks
|
0x03
|
|
INVENTORY_NOTECARD
|
7
|
notecards
|
0x07
|
|
INVENTORY_OBJECT
|
6
|
objects
|
0x06
|
|
INVENTORY_SCRIPT
|
10
|
scripts
|
0x0A
|
|
INVENTORY_SOUND
|
1
|
sounds
|
0x01
|
|
INVENTORY_TEXTURE
|
0
|
textures
|
0x00
|
Note: Inventory constants are not bitflags and thus should not be used with Bitwise operators.
Example:
// 获得该 object 的第 1 个 inventory notecard
llGetInventoryName(INVENTORY_NOTECARD, 0)
相关的函数有: llGetInventoryKey and llGetInventoryNumber
dataserver(key queryid, string data)
当 the requested data 返回时就会 trigger 该 event handler 。
通过调用函数 llGetNotecardLine , llGetNumberOfNotecardLines , llRequestAgentData , llRequestInventoryData , and llRequestSimulatorData 就会要求 request data ,从而 trigger 该 event 。
参数 queryid 是上述函数调用时返回的 key 。
参数 data 是 requested data 。
由于多个函数都能够 trigger dataserver event ,因此要通过参数 queryid 来判断是来自哪一个。
Note: Dataserver requests
会 trigger all dataserver() events in all scripts within the same prim where the request was made , 但 dataserver() events 无法被 trigger in other prims in the same linked object.Remember:
错误的 requests 会失败,但不会抛出任何 error ,而且不会触发 dataserver() event ( 例如:如果 a notecard line is requested, 但所提供的指向 a notecard 的 key 是错误的,那么 request data 失败 ) . 可以通过 timer 来 check 在 request data 后的一段时间内如果 no dataserver() event 发生,就表明 request failed 。
!!注意: dataserver 很慢,因此慎用该 event !!!
Example: 在后面有一个结合 llGetNotecardLine 的例子
key llGetNotecardLine(string name, integer line)
该函数是获取参数 name 所指定的 notecard 里参数 line 所指定的那一行的 data 。
当 data 返回的时候,就会触发 dataserver event 。 Notecard 里的 line number 是从 0 开始的。如果 requested line 已经超过 the end of the notecard , dataserver event 就会返回一个常量 EOF ("End Of File") string.
llGetNotecardLine 的返回值是一个 key , 它会作为参数 queryid 值传递给 dataserver event 。
参数 name 可以是 a notecard name ( 该 notecard 必须在该 object 的 inventory 里 ),也可以是 a key pointing to a notecard ( 该 notecard 不需要在该 object 的 inventory 里 ). 对于第二种情况,你要注意的是 当你 edit a notecard 时,它的 key 会变 !
如果参数 name 没有指定 a valid notecard, or 指定的 notecard is empty, 那么就会抛出 error : "Couldn't find notecard NAME"
注意 :
1. 每一行的 data 不能超过 255 characters ,超过的部分会被 cut
2. Requests from a notecard that contain embedded inventory items 总是返回 EOF ( 当然 dataserver event 会被触发 )
3. 调用该函数会 delays the script for 0.1 seconds.
2. Requests from a notecard that contain embedded inventory items 总是返回 EOF ( 当然 dataserver event 会被触发 )
3. 调用该函数会 delays the script for 0.1 seconds.
Example:
integer gLine = 0; // current line number
key gQueryID; // id used to identify dataserver queries
default {
state_entry() {
gQueryID = llGetNotecardLine(“notecard1”, gLine); // request first line
}
dataserver(key query_id, string data) {
if (query_id == gQueryID) {
if (data != EOF) { // not at the end of the notecard
llSay(0, (string)gLine+": "+data); // output the line
// increase line count
++gLine;
// request next line
gQueryID = llGetNotecardLine(“notecard1, gLine);
}
}
}
}
key llGetNumberOfNotecardLines(string name)
返回参数 name 所指定的 notecard 包含的行数,返回行数时会 trigger dataserver event.
该函数 的返回值是一个 key , 它会作为参数 queryid 值传递给 dataserver event 。 如果参数 name 没有指定 a valid notecard, or 指定的 notecard is empty, 那么就会抛出 error : "Couldn't find notecard NAME" , 而且 dataserver event 也不会被触发 ( 注意:对 empty notecard 调用函数 llGetNotecardLine 会触发 dataserver event ,返回的 data 为 EOF ) 。 Requests from a notecard that contain embedded inventory items 总是返回 EOF ( 当然 dataserver event 会被触发 )
Note:
调用该函数会 delays the script for 0.1 seconds. Example:
default {
state_entry() {
llGetNumberOfNotecardLines("somenotecard");
}
dataserver(key queryid, string data) {
// note how the returned value is already a string
llSay(0, "This notecard has " + data + " lines.");
// if you want to use it as a number, you will have to cast it to an integer:
integer lines = (integer)data;
}
}
changed(integer change)
当 the prim/object 的 properties 发生变化时,就会触发 changed event 。
参数 change 是 a bitfield ,它是由一个 or 多个 下列值合并而成的:
|
Constant
|
Value
|
Indicates
|
|
|
CHANGED_INVENTORY
|
0x1
|
changed object inventory (could include an item being added, removed, or renamed, or a notecard being edited and saved).
|
Details
|
|
CHANGED_COLOR
|
0x2
|
changed object color or transparency
|
|
|
CHANGED_SHAPE
|
0x4
|
changed object shape (box to cylinder, for example), cut, hollow amount/shape, twist, top size, or shear
|
|
|
CHANGED_SCALE
|
0x8
|
changed object scale.
|
Details
|
|
CHANGED_TEXTURE
|
0x10
|
changed object texture: offset, repeats, rotation, and reflection/bump maps (but not transparency -- that's CHANGED_COLOR )
|
|
|
CHANGED_LINK
|
0x20
|
linking or delinking (also when an avatar sits on or unsits from the object).
|
Details
|
|
CHANGED_ALLOWED_DROP
|
0x40
|
An item was dropped (into this object's inventory) that was only allowed by the llAllowInventoryDrop function. This allows the object to identify items dropped by anyone who doesn't have modify permissions on the object.
|
|
|
CHANGED_OWNER
|
0x80
|
The ownership of the object changed. This value is passed when an object is deeded to a group, when an object is purchased, or when a newly-purchased object is rezzed.
|
Details
|
|
CHANGED_REGION
|
0x100
|
The object changed regions/sims.
|
Details
|
|
CHANGED_TELEPORT
|
0x200
|
The object has been teleported.
|
Details
|
Details
| Constant or Value: | changed() is triggered: | changed() is not triggered: |
| CHANGED_INVENTORY |
|
|
| CHANGED_SCALE |
|
|
| CHANGED_LINK |
|
|
| CHANGED_OWNER |
|
|
| CHANGED_REGION |
|
|
| CHANGED_TELEPORT |
|
(As of Second Life 1.16.0 (5) this is not accurate. Teleporting into no-script land will cause the event to trigger once you move onto script-enabled land, as though you had just teleported.) |
Aside from the above, the changed() event is also not triggered:
- when an object changes position. (Use moving_start() and moving_end().)
- when an object changes rotation.
- when changing the object's name or description.
- when changing the object's group. (not deeding the object to a group -- that'll trigger CHANGED_OWNER)
- when toggling "Share with group", "Allow anyone to move", "Allow anyone to copy", setting the object "For Sale", changing any of the sale settings, or setting "Next owner can:".
- when toggling "Lock", "Physics", "Temporary" or "Phantom".
- when setting prim material.
- when using llSetText.
- when using llParticleSystem.
- in a worn attachment when the owner attaches or detaches it. (Use attach().)
- in a worn attachment when the wearer sits on something.
- when the object is selected/edited.
因此它使用的是 ”&” or “|” 等位操作符 。例如:代码总是使用
if (change & CHANGED_LINK)
而不是使用
if (change == CHANGED_LINK )
Notes:
- The change parameter describes only what type of change happened, not the difference between the original and changed versions of the object. If you need to determine exactly what changed, the script must store the relevant properties and compare the values from before and after the change.
- Prim/object position and rotation are not currently detected when changed but can be via a timer and llGetRot and llGetPos. Position changes can also be detected by using the moving_start and moving_end events.
- When an avatar sits on an object, they seem to become part of the linkset.
- A changed() event is raised with CHANGED_LINK as the parameter when an avatar sits on an object or un-sits. To find out what happened, use llAvatarOnSitTarget which returns the NULL_KEY if no avatar is sitting on the object, or the key of the avatar that is sitting at the sit target.
Example 1 当一个 avatar 坐在 object 上时, show info “get off” and 强制他 stand up:
default {
state_entry() {
// needed for llAvatarOnSitTarget to work
llSitTarget(<0, 0, 0.1>, ZERO_ROTATION);
}
changed(integer change) { // something changed
if (change & CHANGED_LINK) { // and it was a link change
// llSleep(0.5); // llUnSit works better with this delay
key av = llAvatarOnSitTarget();
if (av) { // somebody is sitting on me
llSay(0, "Get off!"); // say in chat when person is remove from prim
llUnSit(av); // unsit him
}
}
}
}
Example 2:
changed( integer change)
{
if(( change & CHANGED_OWNER) || (change & CHANGED_INVENTORY) )
{
loadNoteCard();
}
}