Ieldra Posted September 5, 2007 Share Posted September 5, 2007 I've been looking for a way to check the distance to a certain point in an area. Since the Range() trigger only checks the distance to objects, I've been thinking of using an invisible creature. Some questions about this: (1) What I want to do is to start a cutscene at the entrance point of an area, after the PC enters that area, and once (s)he is a certain distance away from this (only) entrance point. I don't want it to happen immediately, I don't want it to happen on top of the PC (NPCs aren't a consideration at this point), and I don't want it to happen when the PC is too far away to see the place. Is there a better way to do this than using an invisible creature for distance checking? (2) Is there a pre-existing invisible creature I can use in the game, preferrably of rabbit size or even smaller, or must I create one? (3) This will happen in a confined space, so is there a chance that stumbling over the invisible creature will influence the PC's movements - such as making it impossible to walk along a narrow corridor if the invisible creature is present - or will that not be a problem? (4) I've been thinking of using fixed coordinates as an alternative. The problem with is this that the area to check would be an approximate circle. It could be simplified to rhombus-shaped one, but since math functions seem not to be implemented in the scripting language, both would get rather complicated. I'll appreciate any advice. How can such a simple task get so complicated...? Link to comment
Ieldra Posted September 5, 2007 Author Share Posted September 5, 2007 Uh...sorry wrong forum. Could someone move this to the Q&A forum, please? Link to comment
Kulyok Posted September 5, 2007 Share Posted September 5, 2007 If it is your own area, I'd suggest implementing a trigger - just the way it happens with Jaheira over Khalid's death. See DLTCEP tutorials(downloaded with DLTCEP - PPG modlist has the links) for instructions. If you are trying this in an existing area, writing a trigger in via WeiDU could work, as well. I recall CamDawg posting some examples in Q&A recently. (I definitely recall there was something like this, 'cause I remember jcompton's "It's so much easier in WeiNGINE!" post). Link to comment
aVENGER_(RR) Posted September 5, 2007 Share Posted September 5, 2007 As Kulyok already said, it would be easier to simply draw an Info Trigger and then assign the appropriate script to it. You can either use DLTCEP to do this, or you can patch the trigger into the area via WeiDU which is slightly more complicated. As for the script, I guess you'll need something along these lines: IF Global("SomeGlobal","GLOBAL",0) // If the cutscene didn't already occur Range(Player1,12) // and the protagonist is nearby !Range(Player1,4) // but (s)he is not on top of the trigger THEN RESPONSE #100 SetGlobal("SomeGlobal","GLOBAL",1) // set the global indicating that the cutscene has triggered StartCutSceneMode() . . . . <some cutscene commands> . . . EndCutSceneMode() END EDIT - I just noticed that you didn't actually ask for two cutscenes (as I had hastily assumed ) so I've shortened the code. Link to comment
Guest Guest Posted September 5, 2007 Share Posted September 5, 2007 Thanks. Yes, my script would look like that. Unfortunately, it is in existing game area, so I'll need to use the patch in method. I'll have a look into IESDP and then try it. BTW: I have to say I consider myself lucky for actually understanding that tp2 code, but if this is "slightly more complicated", I'm beginning to wonder what "considerably more complicated" might be... 50+ lines of code for nothing but a range check... and all this for an as-yet simple mod NPC making a dramatic entrance (I'll post something more about it once it's at least playable). Link to comment
aVENGER_(RR) Posted September 5, 2007 Share Posted September 5, 2007 Heh, don't worry. It may seem a bit intimidating at first, but once you start experimenting and actually using the code it all comes together quite nicely. If you'd like, I could post some of the modified code which I'll be using for RR v3.8. It has much more comments which make things somewhat more understandable and easier to remember (well, for me at least ). Link to comment
Ieldra Posted September 5, 2007 Author Share Posted September 5, 2007 If you'd like, I could post some of the modified code which I'll be using for RR v3.8. It has much more comments which make things somewhat more understandable and easier to remember (well, for me at least ). I would appreciate that. There's never too much commented sample code if you're trying a new programming language (for all practical purposes, WeiDU is exactly that). EDIT: I've looked into the file format description and it's all very straightforward. It's only the tp2 code that looks complicated. I'd still like to see your code. Link to comment
aVENGER_(RR) Posted September 5, 2007 Share Posted September 5, 2007 Ok, here you go then. // Modifying AR0800 to include the new CoC ambush triggers (code based on pro5's Dragon Trigger from the BG1 NPC project) COPY_EXISTING ~AR0800.ARE~ ~override~ // Graveyard district CoC trigger 1 (bottom exit) READ_LONG 0x54 "actor_off" READ_LONG 0x5c "info_off" READ_SHORT 0x5a "info_num" READ_LONG 0x60 "spawn_off" READ_LONG 0x68 "ent_off" READ_LONG 0x70 "cont_off" READ_LONG 0x78 "item_off" READ_LONG 0x7c "vert_off" READ_SHORT 0x80 "vert_num" READ_LONG 0x84 "amb_off" READ_LONG 0x88 "var_off" READ_LONG 0xa0 "bmp_off" READ_LONG 0xa8 "door_off" READ_LONG 0xb0 "anim_off" READ_LONG 0xb8 "tiled_off" READ_LONG 0xbc "song_off" READ_LONG 0xc0 "rest_off" READ_LONG 0xc4 "note_off" SET "Left" = 1675 SET "Top" = 2125 SET "Right" = 1968 SET "Bottom" = 2175 WRITE_SHORT 0x5a ("%info_num%" + 1) INSERT_BYTES "%info_off%" 0xC4 // Insert new blank info point WRITE_ASCII "%info_off%" ~RR#COC01~ // Trigger name WRITE_SHORT ("%info_off%" + 0x20) 1 // Trigger type (trap, info or travel) WRITE_SHORT ("%info_off%" + 0x22) "%Left%" WRITE_SHORT ("%info_off%" + 0x24) "%Top%" WRITE_SHORT ("%info_off%" + 0x26) "%Right%" WRITE_SHORT ("%info_off%" + 0x28) "%Bottom%" WRITE_SHORT ("%info_off%" + 0x2A) 4 // Number of vertices WRITE_LONG ("%info_off%" + 0x2C) "%vert_num%" // First vertex index WRITE_SHORT ("%info_off%" + 0x34) 34 // Cursor type WRITE_SHORT ("%info_off%" + 0x60) 256 // Flags (i.e. trigger is initially deactivated) WRITE_ASCII ("%info_off%" + 0x7C) ~RR#CGRAV~ #8 // Trigger script name PATCH_IF NOT ("%actor_off%" < "%info_off%") BEGIN WRITE_LONG 0x54 ("%actor_off%" + 0xC4) END PATCH_IF NOT ("%spawn_off%" < "%info_off%") BEGIN WRITE_LONG 0x60 ("spawn_off" + 0xC4) END PATCH_IF NOT ("%ent_off%" < "%info_off%") BEGIN WRITE_LONG 0x68 ("ent_off" + 0xC4) END PATCH_IF NOT ("%cont_off%" < "%info_off%") BEGIN WRITE_LONG 0x70 ("cont_off" + 0xC4) END PATCH_IF NOT ("%item_off%" < "%info_off%") BEGIN WRITE_LONG 0x78 ("item_off" + 0xC4) END PATCH_IF NOT ("%vert_off%" < "%info_off%") BEGIN WRITE_LONG 0x7c ("vert_off" + 0xC4) END PATCH_IF NOT ("%amb_off%" < "%info_off%") BEGIN WRITE_LONG 0x84 ("amb_off" + 0xC4) END PATCH_IF NOT ("%var_off%" < "%info_off%") BEGIN WRITE_LONG 0x88 ("var_off" + 0xC4) END PATCH_IF NOT ("%bmp_off%" < "%info_off%") BEGIN WRITE_LONG 0xa0 ("bmp_off" + 0xC4) END PATCH_IF NOT ("%door_off%" < "%info_off%") BEGIN WRITE_LONG 0xa8 ("door_off" + 0xC4) END PATCH_IF NOT ("%anim_off%" < "%info_off%") BEGIN WRITE_LONG 0xb0 ("anim_off" + 0xC4) END PATCH_IF NOT ("%tiled_off%" < "%info_off%") BEGIN WRITE_LONG 0xb8 ("tiled_off" + 0xC4) END PATCH_IF NOT ("%song_off%" < "%info_off%") BEGIN WRITE_LONG 0xbc ("song_off" + 0xC4) END PATCH_IF NOT ("%rest_off%" < "%info_off%") BEGIN WRITE_LONG 0xc0 ("rest_off" + 0xC4) END PATCH_IF NOT ("%note_off%" < "%info_off%") BEGIN WRITE_LONG 0xc4 ("note_off" + 0xC4) END // Add 4 new vertices READ_LONG 0x54 "actor_off" READ_LONG 0x5c "info_off" READ_SHORT 0x5a "info_num" READ_LONG 0x60 "spawn_off" READ_LONG 0x68 "ent_off" READ_LONG 0x70 "cont_off" READ_LONG 0x78 "item_off" READ_LONG 0x7c "vert_off" READ_SHORT 0x80 "vert_num" READ_LONG 0x84 "amb_off" READ_LONG 0x88 "var_off" READ_LONG 0xa0 "bmp_off" READ_LONG 0xa8 "door_off" READ_LONG 0xb0 "anim_off" READ_LONG 0xb8 "tiled_off" READ_LONG 0xbc "song_off" READ_LONG 0xc0 "rest_off" READ_LONG 0xc4 "note_off" WRITE_SHORT 0x80 ("%vert_num%" + 4) INSERT_BYTES ("%vert_off%" + (0x04 * "%vert_num%")) 0x10 WRITE_SHORT ("%vert_off%" + 0x04 * "%vert_num%") 1675 // Vertex1.X WRITE_SHORT ("%vert_off%" + 0x04 * "%vert_num%" + 2) 2175 // Vertex1.Y WRITE_SHORT ("%vert_off%" + 0x04 * "%vert_num%" + 4) 1700 // Vertex2.X WRITE_SHORT ("%vert_off%" + 0x04 * "%vert_num%" + 6) 2125 // Vertex2.Y WRITE_SHORT ("%vert_off%" + 0x04 * "%vert_num%" + 8) 1968 // Vertex3.X WRITE_SHORT ("%vert_off%" + 0x04 * "%vert_num%" +10) 2132 // Vertex3.Y WRITE_SHORT ("%vert_off%" + 0x04 * "%vert_num%" +12) 1957 // Vertex4.X WRITE_SHORT ("%vert_off%" + 0x04 * "%vert_num%" +14) 2175 // Vertex4.Y PATCH_IF NOT ("%actor_off%" < "%vert_off%") BEGIN WRITE_LONG 0x54 ("%actor_off%" + 0x10) END PATCH_IF NOT ("%info_off%" < "%vert_off%") BEGIN WRITE_LONG 0x5c ("info_off" + 0x10) END PATCH_IF NOT ("%spawn_off%" < "%vert_off%") BEGIN WRITE_LONG 0x60 ("spawn_off" + 0x10) END PATCH_IF NOT ("%ent_off%" < "%vert_off%") BEGIN WRITE_LONG 0x68 ("ent_off" + 0x10) END PATCH_IF NOT ("%cont_off%" < "%vert_off%") BEGIN WRITE_LONG 0x70 ("cont_off" + 0x10) END PATCH_IF NOT ("%item_off%" < "%vert_off%") BEGIN WRITE_LONG 0x78 ("item_off" + 0x10) END PATCH_IF NOT ("%amb_off%" < "%vert_off%") BEGIN WRITE_LONG 0x84 ("amb_off" + 0x10) END PATCH_IF NOT ("%var_off%" < "%vert_off%") BEGIN WRITE_LONG 0x88 ("var_off" + 0x10) END PATCH_IF NOT ("%bmp_off%" < "%vert_off%") BEGIN WRITE_LONG 0xa0 ("bmp_off" + 0x10) END PATCH_IF NOT ("%door_off%" < "%vert_off%") BEGIN WRITE_LONG 0xa8 ("door_off" + 0x10) END PATCH_IF NOT ("%anim_off%" < "%vert_off%") BEGIN WRITE_LONG 0xb0 ("anim_off" + 0x10) END PATCH_IF NOT ("%tiled_off%" < "%vert_off%") BEGIN WRITE_LONG 0xb8 ("tiled_off" + 0x10) END PATCH_IF NOT ("%song_off%" < "%vert_off%") BEGIN WRITE_LONG 0xbc ("song_off" + 0x10) END PATCH_IF NOT ("%rest_off%" < "%vert_off%") BEGIN WRITE_LONG 0xc0 ("rest_off" + 0x10) END PATCH_IF NOT ("%note_off%" < "%vert_off%") BEGIN WRITE_LONG 0xc4 ("note_off" + 0x10) END Link to comment
Ieldra Posted September 5, 2007 Author Share Posted September 5, 2007 Great. I think I've got it. Now, to another question. What I really need is something like a distance trigger - something is supposed to happen if the party is *off* a certain circumscribed area they appear in when they enter the map. I suppose I could instead set the trigger area to the rest of the room, but the shape of the area would be, well, interesting. I wonder if I could use an octagonal trigger area and to script it like this: Trigger script does: IF !Global("IxCutsceneTrigger","ARnnnn",0) // global exists, and !Global("IxCutsceneTrigger","ARnnnn",9) // cutscene hasn't yet happened THEN RESPONSE #100 IncrementGlobal"(IxCutsceneTrigger","ARnnnn",-1) END Area Script does: IF Global("IxCutsceneTrigger","ARnnnn",2) // trigger script has done nothing for one or two cycles THEN RESPONSE #100 SetGlobal("IxCutsceneTrigger","ARnnnn",9) // set "cutscene happened" indicator and start the scene (Cutscene Code) END /* Increment the global - I don't know what IncrementGlobal does if its argument variable doesn't exist, so I need to check for non-existence first */ IF Global("IxCutsceneTrigger","ARnnnn",0) THEN RESPONSE #100 SetGlobal("IxCutsceneTrigger","ARnnnn",1) END IF GlobalLT("IxCutsceneTrigger","ARnnnn",9) THEN RESPONSE #100 IncrementGlobal("IxCutsceneTrigger","ARnnnn",1) END I presuppose that the trigger fires once per cycle if any party member is in the area (i.e. not twice if two are, for instance). Does this look as if it could work? As for the situation involved: the party appears as if per Teleport, similar to the way you appear in the Planar Sphere using the Planar Sphere Return mod, only you appear near to the center. Suppose I would want something to happen once the party is far enough away from the center of the room, but at least one party member is still in it and can see what happens. Thus the need for an "off" trigger. Link to comment
aVENGER_(RR) Posted September 6, 2007 Share Posted September 6, 2007 I suppose I could instead set the trigger area to the rest of the room, but the shape of the area would be, well, interesting. You can use IsOverMe() or Entered() for determining when a PC has stepped on the trigger. I'm not 100% sure, but the trigger may have to be of the Trap type for this to work. Link to comment
Avenger Posted September 6, 2007 Share Posted September 6, 2007 There is also a WalkedToTrigger trigger, but i think it requires clicking on it Link to comment
Ieldra Posted September 6, 2007 Author Share Posted September 6, 2007 Thanks, Avenger and aVENGER_[RR], but these triggers won't work for my purpose, because they can only be used in trigger scripts. The kind of check I need would be: IF Global("IxCutsceneTrigger","ARnnnn",0) !IsOverMe(Player1) !IsOverMe(PartyMember2) ....etc. THEN RESPONSE #100 SetGlobal("IxCutsceneTrigger","ARnnnn",1) END (and then check the global in the area script for starting the cutscene) But the condition will never become true, since it would only do so if no party members are in the trigger region, which means that the trigger won't fire and this piece of code will not be reached. There would only be a way around this if the active object could be set to the trigger region for a block of code. So far I have only seen this in cutscenes with CutsceneId. For actions there is ActionOverride. But I don't suppose something similar exists for conditions - at least I have found nothing in IESDP. Link to comment
Avenger Posted September 6, 2007 Share Posted September 6, 2007 Invisible invulnerable rats or birds are useful, they don't have personal space. Why can't you use trigger scripts? if IsOverMe([PC]) then ... Something similar was implemented in DLTC, there are trigger regions which don't need to be entered but their script runs and detects if someone goes near them (causing an autosave before the ogre encounter). IF Global("InitSave","DL0100",0) Range([PC],10) THEN RESPONSE #100 SetGlobal("InitSave","DL0100",1) SaveGame(0) END Link to comment
Ieldra Posted September 6, 2007 Author Share Posted September 6, 2007 Invisible invulnerable rats or birds are useful, they don't have personal space. Ah, very good to know to know that. Why can't you use trigger scripts? If you've read what I'd like to do, you'll notice that this does not work for triggers where something is supposed to happen when all party members have left the area. I assume, of course, that trigger scripts only start running if anyone is on the trigger. If they actually run all the time, like area scripts, then it would work, but that would be very inefficient, since every trap in an area would have its script running all the time. But hey, I don't know the game engine...do trigger scripts run all the time or do they only start running if, well, triggered. Link to comment
Avenger Posted September 6, 2007 Share Posted September 6, 2007 Trigger scripts run always As you can see in my previous post. Door scripts start running when the door was first accessed (after a reload). Container scripts also run always (i think). Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.