Tutorials

 Reply to this postStart new topic

[CLEO/SCM | Tut] Functional Doors

Deji
post Dec 23 2010, 04:57 AM
Post #1


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



Doors


It's not very often someone makes a tutorial about doors. Which is a shame. It's not too much to handle (get it? lol). It's a pretty basic tutorial overall but I've not made a tutorial for beginners in a while. And since I'm tryna practise my forum presentation, I'll make a fancy list of subjects.


Creating A Door




Further Customisation (Advanced)




Creating A Door

Models


Unfortunately, we can't just use any model for our door. Doors have special attributes which allow them to be created by the SCM automatically. You can use MEd to browse for any door model. Anything that looks like a door probably has the ability to be created as one. The door models will probably be in a file labeled "dynamic", which is where most of the objects that are useful for us can be found (also check out files with "xref" in the label - they're made to be used widely, too).

Once you've found a door (I'm gonna use model 1498/#GEN_DOOREXT03), load its model in your script:

SANNY
{$CLEO}
0247: load_model 3077

:Loading
8248:   not model 3077 available
else_jump @Create
wait 0  // no, the model isn't loaded.. lets wait for a bit.
jump @Loading  // rest over, lets go check if that model's available yet!

:Create
0A93: end_custom_thread




Creation


Now to create the door in the :Create thread. You should know where you want your door and have the coordinates all ready. If you're not sure how to get the door positioned right, in absense of a debugger; use MEd to put the object into your map. The controls should make it easy enough to position it perfectly within the door frame, assuming that's where you'd want to create a door.

I've just chosen a very random place near to where I spawn. Add the line respectively:
SANNY
0107: 0@ = create_object 3077 at -803.0488 2426.7722 -100.0


Because I'm lazy, I used -100.0 as the Z Coordinate for the door. This makes the game automatically put the door onto the ground, thus saving me from having to get the ground height. However, this only works if the player is near that spot when the door is created (and the map there is rendered properly) - so you may want to put the exact coordinates if you know them.



Opening


So there we have it... A door that blocks a doorway and doesn't move at all. Really? You want the door to move?! Alright, there's actually a way.

SANNY
0905: set_door 0@ locked 0


This unlocks the door, allowing any entity to pass through it. It will move like a normal door. All the hard work is done for you! Note, that it only unlocks the door once. Once the door has been opened, it will lock again when it gets closed.


So, we should have our whole, very simple working script:
SANNY
{$CLEO}
0247: load_model 3077

:Loading
8248:   not model 3077 available
else_jump @Create
wait 0  // no, the model isn't loaded.. lets wait for a bit.
jump @Loading  // rest over, lets go check if that model's available  yet!

:Create
0107: 0@ = create_object #GEN_DOOREXT03 at -803.0488 2426.7722 156.0

:KeepOpenable
wait 100
0905: set_door 0@ locked 0
jump @KeepOpenable


Notice that I've kept 0905 in a loop, to keep the door freely moving. The usage of doors in SCM suggests it should only really be used with temporary doors, such as the doors of CJ's girlfriends, which only open once to let any of them through. The rest of the time, they are non-functional.



Further Customisation (Advanced)
Setting Open Angle


The whole basis of this tutorial is that I found an offset in the object structure which I set out to figure out. Eventually, I found that it had something to do with rotation and looking into another offset revealed that the opcode 0905 enabled this value to actually get used.

After experimenting, it became clear that the float offset limited the angle of the doors. By default, doors are set to rotate 180 degrees. 90 degrees one way, 90 degrees the other. This float isn't specifically an angle. I can't quite figure out what it is, really. It's easy to keep setting the values until the desired effect is met, but I've not spent enough time with it to figure out the exact relevance to the angle.

Anyway, the float is located at CObject+0x158. If the value isn't over -1000.0, the object has default rotation. Set it to small values (likely between -3.6 to 3.6).

SANNY
0A98: 15@ = object 0@ struct
000A: 15@ += 0x158
0A8C: write_memory 15@ size 4 value 1.0 virtual_protect 0


The door 0@ will open partially.


--------------------
Go to the top of the page
 
+Quote Post
Deji
post Dec 23 2010, 05:05 AM
Post #2


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



F for presentation laugh.gif


--------------------
Go to the top of the page
 
+Quote Post
Adler
post Dec 23 2010, 07:22 AM
Post #3


Devil's Advocate

Group Icon

Posts: 413
From: CA US
Joined: 26-July 09



A for effort lol. I'm sure someone will find this useful. tongue.gif

Keep on digging for that gold Deji. wallbash.gif

This post has been edited by Adler: Dec 23 2010, 07:23 AM


--------------------
Go to the top of the page
 
+Quote Post
Deji
post Jun 27 2011, 06:30 PM
Post #4


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



I ran into some problems trying to make swinging doors. Turns out functional doors are made only for CJ's girlfriends to walk through. They walk through once and everythings okay.

However, when you're trying to make one for the player to walk through, things go a bit wrong. Every time CJ goes through a door, it's set to lock again. And unfortunately, we can't just loop the opcode to unlock the door because then the doors do buggy things like not closing after they are opened.. So basically we have a door that moves when the player walks through and stays there. As if there was carpet underneath and the door was too low (surely everyone has known a door like this).


There is a solution. While setting the door to "unlocked" when it's already unlocked causes the door to stay in once place, setting the door to "unlocked" straight after it's locked works perfectly:
SANNY
if 0471:   actor $PLAYER_ACTOR near_object_in_rectangle $MotelDoor[0] radius 8.0 8.0 sphere 0
then
    0A98: 1@ = object $MotelDoor[0] struct
    000A: 1@ += 0x40
    0A8D: 2@ = read_memory 1@ size 4 virtual_protect 0
    if 08B7:   test 2@ bit 3  // has the door closed and locked?
    then 0905: set_door $MotelDoor[0] lock 0  // unlock it and allow it to swing
    end
end

(bit of altered Vigilante Justice source code here)

Works beautifully.


--------------------
Go to the top of the page
 
+Quote Post
Spider-Vice
post Jun 27 2011, 07:09 PM
Post #5


In motus...

Group Icon

Posts: 361
From: Portugal
Joined: 28-May 09



Deji is bumping topics ninja.gif VJ is near.
Go to the top of the page
 
+Quote Post
Deji
post Jun 27 2011, 07:20 PM
Post #6


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



What an assumption tongue.gif


--------------------
Go to the top of the page
 
+Quote Post
Reply to this postStart new topic

3 User(s) are reading this topic (3 Guests and 0 Anonymous Users)
0 Members: