How to detect if object is in use?

Discussion about Mods for Prison Architect

Moderator: NBJeff

User avatar
dsdude123
level2
level2
Posts: 77
Joined: Tue May 27, 2014 2:40 am
Location: Seattle,WA
Contact:

How to detect if object is in use?

Postby dsdude123 » Tue Sep 06, 2016 7:31 am

I'm currently working an update for one of my mods and I need to have a script that will detect whether a computer is in use by a prisoner and then perform a certain action depending on if the object is in use. I've dug through quite a few sites and haven't been able to find anything on how to do this. Any ideas?
murgh
level2
level2
Posts: 232
Joined: Sat Jan 30, 2016 11:52 am

Re: How to detect if object is in use?

Postby murgh » Tue Sep 06, 2016 8:18 am

Doesn't this info get saved on the object itself? Just have some prisoner using the computer and look in the savegame how it's dealing with it. I guess it's linking the Id.i and Id.u from the prisoner to the computer.
User avatar
dsdude123
level2
level2
Posts: 77
Joined: Tue May 27, 2014 2:40 am
Location: Seattle,WA
Contact:

Re: How to detect if object is in use?

Postby dsdude123 » Tue Sep 06, 2016 8:15 pm

Okay so I have managed to find the following while messing with the save files. When a prisoner is using an object to satisfy a need, a Target.i and Target.u value is assigned to the prisoner.

In my case, the following shows under a prisoner using a laptop:

Code: Select all

 BEGIN Needs     
            Timer                14.15665 
            Action               Use 
            Priority             6 
            ComplainNeedId.i     8 
            ComplainNeedId.u     5010016 
            Target.i             1336 
            Target.u             6991817
         


That Target.u value points to the Id.u in following string which contains a ObjId.u that matches the Id.u of the laptop:

Code: Select all

BEGIN "[i 1336]"   Type 3  Pos.x 146.5000  Pos.y 33.50000  BroadcastSlotId -1  Id.i 1336  Id.u 6991817  ObjId.i 2299  ObjId.u 3820328  ConsumerId.i 3346  ConsumerId.u 5010008  Broadcaster.i -1  Broadcaster.u -1  END


This string is located in the ActiveNeedProviders section of the NeedsLibrary section of the file. Now I need to figure out how read this value.

Anyone know how to get this value from ActiveNeedProvider? Getting the Target.u from the prisoner is easy but now I just need to figure out how to use that value to get the ObjId.u from this string.
murgh
level2
level2
Posts: 232
Joined: Sat Jan 30, 2016 11:52 am

Re: How to detect if object is in use?

Postby murgh » Tue Sep 06, 2016 10:34 pm

Code: Select all

function GetObjectsInSquare(theObject,theRange) -- returns target objects in a square around this object, theRange should be an odd number
   Xmin=math.floor(this.Pos.x-theRange/2)
   Xmax=math.ceil(this.Pos.x+theRange/2)
   Ymin=math.ceil(this.Pos.y-theRange/2)
   Ymax=math.floor(this.Pos.y+theRange/2)
   local ListOfObjects = this.GetNearbyObjects(theObject,theRange*1.2)
   for thatObject, distance in pairs(ListOfObjects) do
      if (thatObject.Pos.x>=Xmin and thatObject.Pos.x<=Xmax) and (thatObject.Pos.y>=Ymin and thatObject.Pos.y<=Ymax) then
      -- it's ok, put other stuff here if you need
      else
         ListOfObjects[thatObject]=nil -- remove the out of bounds object from the list
      end
   end
   return ListOfObjects
end   

function ComputerIsUsed()
   nearbyPrisoners = GetObjectsInSquare("Prisoner", 5) -- perhaps 3 will work as well
   if next(nearbyPrisoners) then
      for name,dist in pairs( nearbyPrisoners) do
         if name.Needs.Target.i==this.Id.i and name.Needs.Target.u==this.Id.u then
                            return true
                            break
                        end
                end
       else
           return false
       end
end

function DoOtherthings()
     if ComputerIsUsed() then
        do stuff
     else
        do nothing
   end
end


Let the computer scan it's area, perhaps you can read out the needs.target.i from the prisoner nearby.
Messing with Needs.Action and Needs.Priority went nowhere when I tried to change those for evacuation...

The computer itself doesn't have some kind of info in the save? Isn't Slot0.i and .u loaded perhaps with the prisoners Id.i and u?
Otherwise just compare those and forget about Needs.Target.i
User avatar
dsdude123
level2
level2
Posts: 77
Joined: Tue May 27, 2014 2:40 am
Location: Seattle,WA
Contact:

Re: How to detect if object is in use?

Postby dsdude123 » Tue Sep 06, 2016 11:32 pm

murgh wrote:

Code: Select all

function GetObjectsInSquare(theObject,theRange) -- returns target objects in a square around this object, theRange should be an odd number
   Xmin=math.floor(this.Pos.x-theRange/2)
   Xmax=math.ceil(this.Pos.x+theRange/2)
   Ymin=math.ceil(this.Pos.y-theRange/2)
   Ymax=math.floor(this.Pos.y+theRange/2)
   local ListOfObjects = this.GetNearbyObjects(theObject,theRange*1.2)
   for thatObject, distance in pairs(ListOfObjects) do
      if (thatObject.Pos.x>=Xmin and thatObject.Pos.x<=Xmax) and (thatObject.Pos.y>=Ymin and thatObject.Pos.y<=Ymax) then
      -- it's ok, put other stuff here if you need
      else
         ListOfObjects[thatObject]=nil -- remove the out of bounds object from the list
      end
   end
   return ListOfObjects
end   

function ComputerIsUsed()
   nearbyPrisoners = GetObjectsInSquare("Prisoner", 5) -- perhaps 3 will work as well
   if next(nearbyPrisoners) then
      for name,dist in pairs( nearbyPrisoners) do
         if name.Needs.Target.i==this.Id.i and name.Needs.Target.u==this.Id.u then
                            return true
                            break
                        end
                end
       else
           return false
       end
end

function DoOtherthings()
     if ComputerIsUsed() then
        do stuff
     else
        do nothing
   end
end


Let the computer scan it's area, perhaps you can read out the needs.target.i from the prisoner nearby.
Messing with Needs.Action and Needs.Priority went nowhere when I tried to change those for evacuation...

The computer itself doesn't have some kind of info in the save? Isn't Slot0.i and .u loaded perhaps with the prisoners Id.i and u?
Otherwise just compare those and forget about Needs.Target.i


Checking Slot 0 indeed was the solution. The following code successfully changed the sprite when in use and then changed back once no longer in use:

Code: Select all

function Update( timePassed )
if tonumber(this.Slot0.i) > -1 then
this.SubType = 1 --change display to on
else
this.SubType = 0 --change display to off
end
   

end


It is also to be noted that the need provider in needs.txt must specify to use slot 0 when satisfying the need.

Thanks again!
murgh
level2
level2
Posts: 232
Joined: Sat Jan 30, 2016 11:52 am

Re: How to detect if object is in use?

Postby murgh » Wed Sep 07, 2016 9:12 am

Nice, when checking Slot0 you won't need the getnearbyobjects scan at all, saves some cpu usage :D

Return to “Modding”

Who is online

Users browsing this forum: No registered users and 0 guests