OBSE 18: Association of two objects by array

Post » Fri Jun 25, 2010 5:06 pm

I've been trying to associate two objects by array with little success. Maybe one of you could help.
Is it a good idea to use string map arrays to associate references? Feel free to discuss your opinion, too.


The idea is to mark some location with a marker reference. An AI package tracks the reference, affecting behavior of a creature.
For each creature that the mod changes, give it a unique marker. (One marker for each creature.)


Basic idea:

ref creature          ; some selected creature by external scriptref markerRef         ; marker the AI package targetsarray_var markers     ; the association between creatures and markers!array_var itemshort newMarkerif eval !(markers)                        ; array not initialised before  let markers := ar_Construct StringMapendifForEach item <- markers                   ; check if this creature has a marker already associated  if eval creature := item["key"]    let markerRef := item["value"]        ; already has one, get marker  else    let newMarker := 1                    ; doesn't have one, lets give the creature a new marker  endifloopif newMarker  let markerRef := CloneForm xMarkerRef   ; xMarkerRef is the one created in the CS Editor  let markers[creature] := markerRef      ; associate the creature with the marker  let newMarker := 0endif; do stuff with markermarkerRef.MoveTo player; update creature AIif eval !(creature.GetIsCurrentPackage somePkgWithMarker)  creature.AddScriptPackage somePkgWithMarker  creature.EvaluatePackageendif



This doesn't work. The error goes like: "Invalid operands for operator [."


To make it work you have to do like this:

let markers[$(creature)] := markerRef



The problem is, when calling toString (or the "$" sign) on a reference, it takes the object name if it has one. However, different objects may have the same name.

I just want to associate two objects by taking their references.

It is meant to pass the object ID (or ref) to the StringMap array and check if there is one. If $(creature) passes a string with the name instead of the ID, then it's not good.



What do you propose?
User avatar
Ray
 
Posts: 3472
Joined: Tue Aug 07, 2007 10:17 am

Post » Fri Jun 25, 2010 9:44 am

From a fast look, I think your problem is that you're trying to use references as keys in a string_map, and a reference is not a key. So you have two choices - to comvert the formdId to a string (%i, or GetFormIDString), or to store it in a different way. To convert the formdId to a string is problematic if you store the formdId to a mod-added creature, as part of the formd is its load order. So I instead suggest you use two arrays, markers and creatures, making both normal arrays.

Then do something like this (replaces the two middle ifs in your code):
let i := ar_Find creature creatures    ; check if this creature has a marker already associatedif i >= 0  let markerRef := markers[i]     ; already has one, get markerelse  let i := ar_Size creatures  let creatures[i] := creature  let markerRef := CloneForm xMarkerRef   ; xMarkerRef is the one created in the CS Editor  let markers[i] := markerRef      ; associate the creature with the markerendif

User avatar
Verity Hurding
 
Posts: 3455
Joined: Sat Jul 22, 2006 1:29 pm

Post » Fri Jun 25, 2010 1:33 pm

Thank you! Very nice indeed! :tops:
User avatar
Alexandra Ryan
 
Posts: 3438
Joined: Mon Jul 31, 2006 9:01 am


Return to IV - Oblivion