Jump to content

Detecting objects


i30817

Recommended Posts

This is another failed experiment; maybe the readers have some insight:

 

I wanted to make a autoloot button, like in dungeon siege or KotC

 

I imagined:

1) detecting a pile of loot with a item of interest

2) moving to the pile of loot if needed

3) checking if i have a container on a predefined place (of the type that accepts the item)

3a) put it in the bag

3b) put in the inventory

3c) warn that i can't pick up anything else

 

The plan failed on step 1 already.

 

I tried to use

See([0.POTION])

Or

Detect([0.POTION])

Or

Range([0.POTION], 30)

Or

AreaCheckObject("ARXXXX", [0.POTION])

etc etc etc.

 

They all compiled, but no trigger triggered with these object ids even with potions on the floor. Seems like the [] syntax can only be used to find creatures? What's the point of the object categories in "general" then?

 

There is this action i haven't tried yet;

CopyGroundPilesTo(S:ResRef*,P:Location*)

 

Which i could apparently use to copy all ground items into the same position as the character (think cutscene, they are all stripping the bodies), but then i have the same problem of not having the objects references to move to inventory. And i'm afraid this would break areas and stuff since it has no LOS check.

 

Then i suppose there is the next problem, adding a thing to a bag programmatically.

Link to comment
Seems like the [] syntax can only be used to find creatures?
For the most part, yes. I believe there's one or two values that will actually let you pick up another AI object, but there's no method for determining which object it is.

 

What's the point of the object categories in "general" then?
Unsure. They existed at the very beginning, so my guess is an idea that got scrapped by the time BG was released (they've never been used for anything). I suppose they could have some relation to something that happens in hardcode, but I couldn't guess as to what (and it's not something a mortal would ever find a use for).

 

CopyGroundPilesTo(S:ResRef*,P:Location*)
This moves pile containers to a location (anything on the ground is stored in a container created at the coordinates of the object). I'm unsure as to when the transfer occurs, but I don't think it's something you'd use to get realtime results.

 

Interacting with ground piles is identical to interacting with containers, except that the ground pile has no name (or has random memory junk, since they don't always initialize it when creating the pile container IIRC) or other means to really pick up on it. There is no item on the ground. There is a container at that location that contains an item on the ground (and because of the container type, the engine looks into the first n members of the item list for icons to display at that point).

 

Then i suppose there is the next problem, adding a thing to a bag programmatically.
This cannot be done, period.
Link to comment

ughh.

 

Terrible.

 

What do you mean by:

For the most part, yes. I believe there's one or two values that will actually let you pick up another AI object, but there's no method for determining which object it is.

 

?

Just the normal enemy targeting technique?

 

 

I haven't been able to make CopyGroundPilesTo appear to work.

 

I'm doing:

IF
True()
THEN
RESPONSE #100
DisplayStringHead(Myself, ~I see it~)
CopyGroundPilesTo("AR0602",[0.0])
Continue()
END

(on the BG2 initial area).

 

It displays the string, but it doesn't appear to merge/move the containers.

Link to comment

auto-loot? as in press a hotkey and the selected characters go around the area and pick up given stuff?

 

doable and been done before

 

I used this to add on to a pre-existing party script that I made. it's intent was to pickup ammo after battle since I was using igi's Projectile Retrieval Mod. One thing I did notice tho was that if any arrows, bolts, etc.. were inside a locked and trapped container, they'd be taken out without having unlocked or removed the trap. couldn't figure a way around that tho.

 

feel free to pull whatever ideas from this that you can.

 

BACKUP ~ab_mods/Script_Test/backup~
AUTHOR ~plainab @ forums of G3, PocketPlane & TeamBG~

//----------------
// Hotkey Ability: Ammo Pickup
//----------------
BEGIN ~Hotkey Ability to pickup stuff IF you have a container to put it in~
REQUIRE_PREDICATE !(GAME_IS ~bg1~) ~Script can not run on BG1 sorry. Skipping~
OUTER_INNER_PATCH ~12~ BEGIN
WRITE_BYTE 1 0x0a
READ_ASCII 1 lnl(1)
WRITE_BYTE 0 0x0d
READ_ASCII 0 mnl(1)
READ_ASCII 0 nl(2)
END
//use hotkey to start process
<<<<<<<< inlined/_start.baf
// 0 and slots full change to 1
IF
 Global("ab_invfull","LOCALS",0)
 HasItemSlot(Myself,SLOT_MISC3)
 HasItemSlot(Myself,SLOT_MISC4)
 HasItemSlot(Myself,SLOT_MISC5)
 HasItemSlot(Myself,SLOT_MISC6)
 HasItemSlot(Myself,SLOT_MISC7)
 HasItemSlot(Myself,SLOT_MISC8)
 HasItemSlot(Myself,SLOT_MISC9)
 HasItemSlot(Myself,SLOT_MISC10)
 HasItemSlot(Myself,SLOT_MISC11)
 HasItemSlot(Myself,SLOT_MISC12)
 HasItemSlot(Myself,SLOT_MISC13)
 HasItemSlot(Myself,SLOT_MISC14)
 HasItemSlot(Myself,SLOT_MISC15)
 HasItemSlot(Myself,SLOT_MISC16)
 HasItemSlot(Myself,SLOT_MISC17)
 HasItemSlot(Myself,SLOT_MISC18)
THEN
RESPONSE #100
 SetGlobal("ab_invfull","LOCALS",1)
 Continue()
END
// 1 and at least one slot empty change to 0
IF
 Global("ab_invfull","LOCALS",1)
 OR(16)
  !HasItemSlot(Myself,SLOT_MISC3)
  !HasItemSlot(Myself,SLOT_MISC4)
  !HasItemSlot(Myself,SLOT_MISC5)
  !HasItemSlot(Myself,SLOT_MISC6)
  !HasItemSlot(Myself,SLOT_MISC7)
  !HasItemSlot(Myself,SLOT_MISC8)
  !HasItemSlot(Myself,SLOT_MISC9)
  !HasItemSlot(Myself,SLOT_MISC10)
  !HasItemSlot(Myself,SLOT_MISC11)
  !HasItemSlot(Myself,SLOT_MISC12)
  !HasItemSlot(Myself,SLOT_MISC13)
  !HasItemSlot(Myself,SLOT_MISC14)
  !HasItemSlot(Myself,SLOT_MISC15)
  !HasItemSlot(Myself,SLOT_MISC16)
  !HasItemSlot(Myself,SLOT_MISC17)
  !HasItemSlot(Myself,SLOT_MISC18)
THEN
RESPONSE #100
 SetGlobal("ab_invfull","LOCALS",0)
 Continue()
END

IF
HotKey(%F1%)
THEN
RESPONSE #100
SetGlobalTimer("ab_stuff2store","LOCALS",60)
SetGlobal("ab_dostore","GLOBAL",1)
END
>>>>>>>>
// get hotkey default is E
PRINT ~Change Hotkey assignment? Default is E
[1]Change [2]Leave alone~
ACTION_READLN ~hk~
OUTER_WHILE ((%hk% != 1) AND (%hk% != 2)) BEGIN
PRINT ~Did not understand~
PRINT ~Change Hotkey assignment? Default is E
[1]Change [2]Leave alone~
ACTION_READLN ~hk~
END
OUTER_SPRINT ~F1~ ~E~
ACTION_IF (%hk% = 1) THEN BEGIN
PRINT ~What letter key do you want to use for your Hotkey?~
ACTION_READLN ~F1~
OUTER_WHILE !(~%F1%~ STRING_COMPARE_REGEXP ~[A-Z]~ =0) BEGIN
 PRINT ~Did not understand~
 PRINT ~What letter key do you want to use for your Hotkey?~
 ACTION_READLN ~F1~
END
END

EXTEND_BOTTOM_REGEXP ~party.bs~ ~inlined/_start.baf~
EVALUATE_BUFFER

PRINT ~Please be patient this may take some time.~
PRINT ~Building list dynamically with current base of game files.~

OUTER_SPRINT action1 ~END~
OUTER_SPRINT trigger1 ~THEN~
OUTER_SET y1 = 0

<<<<<<<< inlined/_clearinv.baf
IF
 !See([ENEMY])
 CombatCounter(0)
 ActionListEmpty()
GlobalTimerNotExpired("ab_stuff2store","LOCALS")
Global("ab_invfull","LOCALS",1)
Global("ab_dostore","GLOBAL",%z%)
HasItem("%sto_res%",Player%z%)
THEN
RESPONSE #100
SetGlobal("ab_dostore","GLOBAL",%zy%)
SetGlobal("ab_invfull","LOCALS",0)
StartStore("%sto_res%",Player%z%)
END
>>>>>>>>
COPY_EXISTING_REGEXP GLOB ~.*\.sto~ ~override~
PATCH_IF (%SOURCE_SIZE% >= 156) THEN BEGIN
SPRINT ~sto_res~ ~%SOURCE_RES%~
READ_LONG 0x8 ~store_type~
PATCH_IF (%store_type% = 5) BEGIN
 INNER_ACTION BEGIN
  ACTION_IF (FILE_EXISTS_IN_GAME ~%sto_res%.itm~) THEN BEGIN
COPY_EXISTING ~%sto_res%.itm~ ~override~
 PATCH_IF (%SOURCE_SIZE% >= 114) BEGIN
  READ_BYTE 0x18 ~flags~
  //only do those that are droppable
  PATCH_IF ((%flags% BAND "0b00000100") = "0b00000100")  // droppable
	   AND ((%flags% BAND "0b00001000") = "0b00001000") BEGIN // displayable in shop
   SET doit = 1
  END
 END
BUT_ONLY_IF_IT_CHANGES
ACTION_IF (%doit% = 1) THEN BEGIN
 OUTER_FOR (z=1;z<7;z+=1) BEGIN
  OUTER_SET zy = %z% + 1
  ACTION_IF (%zy% = 7) THEN BEGIN
   OUTER_SET %zy% = 0
  END
  EXTEND_BOTTOM_REGEXP ~party.bs~ ~inlined/_clearinv.baf~
   EVALUATE_BUFFER
 END
END
  END
 END
END
END
BUT_ONLY_IF_IT_CHANGES

<<<<<<<< inlined/_pickup1.baf
IF
 !See([ENEMY])
 CombatCounter(0)
 ActionListEmpty()
 GlobalTimerNotExpired("ab_stuff2store","LOCALS")
 Global("ab_invfull","LOCALS",0)
THEN
 RESPONSE #100
%action1%
>>>>>>>>
OUTER_SET num = 0
OUTER_SET num2 = 0
COPY_EXISTING_REGEXP GLOB ~.*\.itm~ ~override~
SET num = %num% + 1
PATCH_IF (%SOURCE_SIZE% >= 114) BEGIN
//  READ_ASCII offset variable  [ ELSE string  ]  [ ( value )  [ NULL  ]  ]
 READ_ASCII 0x003a ~invicon~ ELSE ~No File~  (8) NULL	 //8 (resref)	  Inventory icon
 READ_ASCII 0x0044 ~groundicon~ ELSE ~No File~(8) NULL	//8 (resref)	  Ground icon
 READ_ASCII 0x0058 ~descicon~ ELSE ~No File~  (8) NULL	//8 (resref)	  Description icon
 //following should weed out many player unusable items
 PATCH_IF ( (FILE_EXISTS_IN_GAME ~%invicon%.bam~)
	 AND (FILE_EXISTS_IN_GAME ~%groundicon%.bam~)
	 AND (FILE_EXISTS_IN_GAME ~%descicon%.bam~) ) BEGIN
  READ_BYTE 0x18 ~flags~
  //only do those that are droppable
  PATCH_IF ((%flags% BAND "0b00000100") = "0b00000100")  // droppable
	 AND ((%flags% BAND "0b00001000") = "0b00001000") BEGIN // displayable in shop
SET num2 = %num2% + 1
SPRINT action1 ~PickUpItem("%SOURCE_RES%")%nl%%action1%~
PATCH_PRINT ~Allowing pickup of %SOURCE_RES%  File #%num2% of %num% file(s) read.~
  END
 END
END
BUT_ONLY_IF_IT_CHANGES
EXTEND_BOTTOM_REGEXP ~party.bs~ ~inlined/_pickup1.baf~
EVALUATE_BUFFER

COPY ~override/party.bs~ ~scripts/party.bs~

 

Link to comment

wanna know what i really think?

 

bioware didn't think of us lazy S.O.B.s when they came up with their code. they were too busy being lazy S.O.B.s themselves.

 

and therefore we get shafted into having massive amounts of code to do the simplest of things.....

Link to comment

autopickup is bad from my experience as the critters drop too much crap. As a consequence, gemrb only has a hotkey to consolidate all the ever visible ground piles under the mouse. And some grouping, but that doesn't always work.

Link to comment

that's why i'd like a "put item in bag" action.

 

But i see that you've already implemented much of what i requested for TobEx in gemrb...

 

any obvious things i requested wrong in that post?

 

I'm hoping for a hotkey that would consolidate the visible, reachable piles next to or under the character, and loot them into sacks if possible (like a cutscene maybe).

 

The "loot" function could also be used to loot unlocked containers too (preferably tripping traps and npc's noticing).

 

As for item filtering, i've read here that things like:

[0.WEAPON.0.MAGIC] are in Object but unusued.

 

They're in the item definitions files, and are read into memory right? And generally consistent? Because they could be used in the filtering function then.

 

Heck, just making the mouse click on the "transfer window" not go to the inventory directly, but the the most specific bag in the inventory that accepts that type of item would help a lot.

Link to comment
What do you mean by:
I believe ANYTHING and maybe another value or two can actually return non-actor objects (triggers, and maybe doors and containers). But there's no way to tell what that object is or to get it to pick out the object you want (it'll just be the closest object). But it's been a long time, so I could be wrong here.

 

It displays the string, but it doesn't appear to merge/move the containers.
My assumption is that it holds the request in memory until the target area is loaded (and then the containers are copied across to the target location). It's not something that would have an effect while you're standing right there in the area. It was designed for a very specific purpose (moving the party away from an area they can never return to from inside a cutscene), so I wouldn't expect it to really work quite right (if at all) when used otherwise.
Link to comment

I observed a effect (in the next post).

 

 

CopyGroundPilesTo("AR0602",[0.0])

 

("AR0602" was the area where i was, the BG2 start dungeon)

 

duplicated the elements on a pile (pile created by dropping a potion).

 

It didn't move it at all, but it DID duplicate the items.

Link to comment

that was already estamblished. This action is used in tob after you kill your first Bhaalspawn at the start. The cutscene takes over immediately and this way you still get to loot that presumptuous fool, even thought you're suddenly in your pocket plane.

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...