Author Topic: Blocking path with a view...  (Read 3624 times)

0 Members and 1 Guest are viewing this topic.

Offline Cloudee1

Blocking path with a view...
« on: July 31, 2014, 10:54:16 AM »
So I have a cave. In this cave, I am using one pic and one room script and depending on which local variables are set as to what actual "cave room" you are in. I have a couple of views that are intended to block the paths when appropriate. The room and views are working beautifully and they are appearing exactly when they should. The problem is that the "footprint" of the view is not large enough on the views that block the east and west passages. Here is a screen shot of the controls so that I can illustrate what I mean. I have inlayed the view next to where it is positioned. The white control area is generated by the view being placed there, but I want it to block the height of the view, just like it does the width.


I have tried setting the nsTop, lsTop, and brTop in an attempt to stretch the footprint of the prop so that it blocks the entire path rather than the small white control area seen above. But all three had no effect. I am pretty sure that the underbits property controls the control color used, but not the size. Any ideas how I can do this with the views properties?

I can always just draw some control lines and program an observeControl or two when needed, but for some reason I think that controlling the underbits height should be accomplishable with properties, I just can't seem to find the right ones.

* Edit:
I have gone one better than the observeControl property of the ego and have actually used the grDRAW_LINE to accomplish my goal. I am not sure why I didn't think of it before. Probably because I have never actually used it... but now I have.

Code: [Select]
  (if(== goSouth 0)
     (southBlock:addToPic())
     Graph(grDRAW_LINE 137 138 137 177 -1 -1 clWHITE)  //  y1 x1  y2  x2
   )

The only weird part about it is the order of the points, with the y's coming before the x. So the above Graph code says draw a line from (138,137) to (177, 137) not on Visual screen, not on Priority screen, White on Control screen.
« Last Edit: July 31, 2014, 12:09:41 PM by Cloudee1 »


Halloween Competition Brass Lantern Prop Competition Groundhog Day Competition

Offline gumby

Re: Blocking path with a view...
« Reply #1 on: August 01, 2014, 07:18:29 PM »
Thank you for this.  I think I had a similar problem with 120 Below and the snowman and never got it resolved.  This will be helpful when I code up rooms for the maze in Zork, sounds just like the scenario you are describing with the multiple cave rooms.
In the Great Underground Empire (Zork port in development)
Winter Break 2012 Rope Prop Competition

Offline Cloudee1

Re: Blocking path with a view...
« Reply #2 on: August 01, 2014, 11:06:23 PM »
It actually works out far better than I thought it was going to go. I currently have close to 100 "rooms" operating off of one script (well actually two because I couldn't get the cave room to reload itself)

Here's what I did...
First I'll start with my jumper script, it is basicly a script I use to transition from one cave room to the other. It also determines if a special room has been reached and if so, loads up the other room instead of the cave room. So basically the only purpose of this room is to jump immediately to a different room.

Code: [Select]
//******************************************************************************
(include "sci.sh")(include "game.sh")                               (script 200)
//******************************************************************************
(use "Controls")(use "Cycle")(use "Feature")(use "Game")(use "Main")(use "Obj")
//******************************************************************************
(instance public rm200 of Rm
(properties picture 800)
  (method (init)
  (super:init())
  (self:setScript(RoomScript))
  )// end method
)// end instance
//******************************************************************************
(instance RoomScript of Script
(properties)
  (method (doit)
  (super:doit())
    UnLoad(rsPIC 800)
    UnLoad(rsSCRIPT scriptNumber)
   
    (switch(caveRoom) // list any special rooms as well as cave exits
    (case 100 = caveRoom 24 // reset to defaults
          = lastCaveRoom 3
          = caveLevel 0
         (send gRoom:newRoom(12))) // outside
        (case 150 = caveRoom 1
          = lastCaveRoom 4
          = caveLevel 4
         (send gRoom:newRoom(15))) // mushroom pool
    (default (send gRoom:newRoom(13))) // Back to cave room
)
  )// end doit method
)// end instance
//******************************************************************************

There are some pretty general global variables set. The current level of the caves, the current room of the caves, and the direction the previous room was.

Code: [Select]
    caveLevel = 0 // current cave level
    caveRoom = 24 // current cave room
    lastCaveRoom = 3 // 0=downLadder, 1=north, 2=east, 3=south, 4=west,5=upLadder

And then comes the cave room script. Just to try and explain it as I go, it will probably be easier to break this down into sections. So we start with the local variables... the goDirections variables are declared and set to 0. There is also a doColor set of variables, these are going to be used to tell ego to observe the color if it needs to. In my case, I used these for the ladders. The ladder down is set in a hole in the middle of the room so the hole can't be walked on. Likewise the ladder going up needs to have the blocking controls set up as well just to make sure it doesn't get walked through.

Code: [Select]
//******************************************************************************
// rm013.sc                                                             
//******************************************************************************
(include "sci.sh")(include "game.sh")                               (script 13)
//*****************************************************************************
(use "main")(use "controls")(use "cycle")(use "game")(use "feature")(use "obj")
//*****************************************************************************
(local
 goNorth = 0
 goEast = 0
 goSouth = 0
 goWest = 0
 
 doYellow = FALSE
 doNavy = FALSE
)
//*****************************************************************************

Then, there is placing ego and this is where one of our global variables come in. Basically the lastcaveroom from above. It isn't really descriptive of what it stores but when I first made it I had a different idea.

Code: [Select]
(instance public rm013 of Rm
(properties picture scriptNumber)
  (method (init)
  (super:init())
  = goToRoom 0
 
  (self:setRegions(950)) // PnC Menu
  (self:setScript(RoomScript)) 

  (switch(lastCaveRoom)
  (case 0 (send gEgo:posn(160 120)loop(3)))//come down ladder
  (case 1 (send gEgo:posn(157 86)loop(2)))//north
  (case 2 (send gEgo:posn(219 110)loop(1)))//east
  (case 3 (send gEgo:posn(157 137)loop(3)))//south
  (case 4 (send gEgo:posn(98 110)loop(0)))//west
  (case 5 (send gEgo:posn(176 93)loop(0)))//come up ladder
  )

Now comes the long boring part, I'll only show a bit of this just to get the point across. Here is where I declare the rooms and how they interconnect. I do this with a nested switch using the other two global variables. First depending on which level ego is on and then what room ego is in. Depending on the room as to which rooms connect to it. This is where our directional local variables come into play. The values given represent the pretend room numbers in the given direction. If the direction should be blocked off, then I leave the value set to 0. Before starting this, it would be a good idea to have your caves mapped out. Whenever you come to a room that needs something special in it, simply init it in that case. If you look, you'll see the ladders that I have up and running. Likewise, in those rooms, I also set the do color local variables I declared to true so that when I init the ego, I know whether or not he needs to be blocked by those colors.

Heres what I did for mapping prior to starting this

1   2   3   4    5   6
7   8   9   10  11  12
...

and then the boring bit of code. Again, this is highly abbreviated. I have a crap ton of rooms running off of this script, and each and every one of them has a case statement devoted to it.

Code: [Select]
  (switch(caveLevel)
  (case 0
  (switch(caveRoom)
     (case 24   
             = goNorth 18
         = goEast 0
         = goSouth 100 // to world map room 12
         = goWest 23
         )
         (case 23   
             = goNorth 0
         = goEast 24
         = goSouth 0
         = goWest 22
         )
         (case 22   
             = goNorth 16
         = goEast 23
         = goSouth 0
         = goWest 0
         )
         (case 21   
             = goNorth 15
         = goEast 0
         = goSouth 0
         = goWest 20
         )
         (case 6   
             = goNorth 0
         = goEast 0
         = goSouth 12
         = goWest 0
         (ladderDown:addToPic())
         = doYellow TRUE
         )
)// end caveRoom switch for level 0
)// end level 0 case
(case 1
(switch(caveRoom)
 
     (case 34   
             = goNorth 28
         = goEast 35
         = goSouth 0
         = goWest 0
         )
         (case 35   
             = goNorth 0
         = goEast 0
         = goSouth 0
         = goWest 34
         
         )
         (case 18   
             = goNorth 0
         = goEast 0
         = goSouth 24
         = goWest 0 
         (ladderUp:addToPic())
         = doNavy TRUE
         )
)// end caveroom switch
)// end caveLevel 1
  )// end caveLevel switch

Now with everything more or less declared, or I at least know which way is what anyway. It is time to init our room blocks and our ego.

Code: [Select]
  (if(== goNorth 0)
  (northBlock:addToPic())
     Graph(grDRAW_LINE 76 134 76 177 -1 -1 clWHITE)//  y1 x1  y2  x2
  )
  (if(== goSouth 0)
  (southBlock:addToPic())
     Graph(grDRAW_LINE 137 138 137 177 -1 -1 clWHITE)//  y1 x1  y2  x2
  )
  (if(== goEast 0)
  (eastBlock:addToPic())
     Graph(grDRAW_LINE 99 231 121 231 -1 -1 clWHITE)//  y1 x1  y2  x2
  )
  (if(== goWest 0)
  (westBlock:addToPic())
     Graph(grDRAW_LINE 101 86 120 86 -1 -1 clWHITE)//  y1 x1  y2  x2
  )
   

  SetUpEgo()
  (if(doYellow)
   (send gEgo:observeControl(ctlYELLOW)init())
  )
  (else
  (if(doNavy)
     (send gEgo:observeControl(ctlNAVY)init())
    )
    (else
     (send gEgo:init())
)
 )
  )// end init method
)// end instance

Beyond that, the only thing I am really doing is resetting my global variables at room transitions. I have this bit in the RoomScripts Doit method. I know I space my code different than most, so I broke one down into separate lines...

Code: [Select]
     (if(>(send gEgo:y) 145)
       = caveRoom goSouth  // reset our global variable to the value held in local variable
       = lastCaveRoom 1 // remember this actually represents direction not a room number
       = goToRoom 200 // off to the jumper script which reloads cave rooms or special rooms
     )
    (if(<(send gEgo:y) 77)  = caveRoom goNorth = lastCaveRoom 3 = goToRoom 200)
    (if(>(send gEgo:x) 233) = caveRoom goEast = lastCaveRoom 4 = goToRoom 200)
    (if(<(send gEgo:x) 80) = caveRoom goWest = lastCaveRoom 2 = goToRoom 200)

and for the click on ladder interactions to illustrate how I handled the level variables.  Of course I am using the point and click template hence all the coding about the  cursor. This bit would be in the RoomScripts handleevent method...

Code: [Select]
// Click on View
(if((> (send pEvent:x) (ladderDown:nsLeft))and
    (< (send pEvent:x) (ladderDown:nsRight))and
    (> (send pEvent:y) (ladderDown:nsTop))and
    (< (send pEvent:y) (ladderDown:nsBottom)))
    (switch(gCurrentCursor)
      (case 999 (send pEvent:type(evMOUSEBUTTON) claimed(FALSE))) // walk
      (case 998 (send pEvent:type(evMOUSEBUTTON) claimed(TRUE))Print("There is a ladder here leading further down into the caves."))// look
      (case 996 (send pEvent:type(evMOUSEBUTTON) claimed(TRUE))Print("The ladder has nothing to say."))// talk
      (case 995 (send pEvent:type(evMOUSEBUTTON) claimed(TRUE))//  get
      (if(send gEgo:inRect(136 94 184 120))
      (switch(caveLevel)
      (case 0 = caveLevel 1 = caveRoom 18 = lastCaveRoom 0)// from level 0  to level 1 and into room 18 from ladder...
      (case 1 = caveLevel 2 = caveRoom 4 = lastCaveRoom 0)
      (case 2 = caveLevel 4 = caveRoom 4 = lastCaveRoom 0)// skipping a level ... just too much maze
)
= goToRoom 200
      )
      (else
      Print("You need to stand in a better spot")
      )
      )// end case
      (default  (send pEvent:type(evMOUSEBUTTON) claimed(TRUE))Print("There is no reason to use that on the ladder."))// item
    )// end current cursor switch
)// end if item

and that is how I did a massive cave labrynth with just 2 scripts... and again I would have only needed 1 if I could have gotten the room to send to itself. I am currently sitting at 10000 heap to go so I could easily grow this another hundred rooms if I was so inclined by simply adding more room number cases or levels in the init section at the top.
« Last Edit: August 02, 2014, 06:29:21 PM by Cloudee1 »
Halloween Competition Brass Lantern Prop Competition Groundhog Day Competition

Offline lskovlun

Re: Blocking path with a view...
« Reply #3 on: August 08, 2014, 12:16:49 PM »
I have tried setting the nsTop, lsTop, and brTop in an attempt to stretch the footprint of the prop so that it blocks the entire path rather than the small white control area seen above. But all three had no effect. I am pretty sure that the underbits property controls the control color used, but not the size. Any ideas how I can do this with the views properties?

I can always just draw some control lines and program an observeControl or two when needed, but for some reason I think that controlling the underbits height should be accomplishable with properties, I just can't seem to find the right ones.
You're on the right track, actually. The brTop etc. properties are used for actor collision checks. Your problem is they are calculated automatically when stuff moves, so you can't change them directly. Instead, you want to create a "base setter" object (there is one in the template game already, it's called NormalBase in Main.sc). This object works its magic inside a doit method, where you calculate the br* properties. After writing your own base setter, all you need to do is set the baseSetter property on the actor in question to point to that object.

The default base setter uses the yStep property to determine the height of the actor's feet and sets the br* properties to cover this area. It may be sufficient in some cases to change the yStep property, but I don't think that is the case for you. Changing it too much will affect the actor's movement.

Offline gumby

Re: Blocking path with a view...
« Reply #4 on: August 08, 2014, 07:30:19 PM »
Would this approach also address some of the issues that we are having with the avoid script?

http://sciprogramming.com/community/index.php/topic,269.0.html
In the Great Underground Empire (Zork port in development)
Winter Break 2012 Rope Prop Competition


SMF 2.0.19 | SMF © 2021, Simple Machines
Simple Audio Video Embedder

Page created in 0.026 seconds with 17 queries.