Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const string MATCHBOX = "matchbox";
- const string WALL = "shelfwall_";
- const string RAY_SEGMENT_FILE = "sdiv";
- void OnStart()
- {
- //#1: Create the detectors & init vats
- CreateDetectors(MATCHBOX,RAY_SEGMENT_FILE,0.5f,10);
- //#2: Set the initial direction
- SetCurrentDir(EAST);
- //#3: Wait until the crate hits the floor (2 seconds)
- AddTimer("TMR_CRATE_MOVE",2.0f,"tmrCrateMotion");
- }
- ///////////////////////////////
- //+ DETECTOR INIT
- ///////////////////////////////
- //Create a set of wall detectors around the matchbox
- void CreateDetectors(string &in asEntity, string &in asFileBase, float afStepSize, int maxDetectors)
- {
- string filename = asFileBase + afStepSize + ".ent";
- //Create the beam of detectors
- for(int i = 0; i < maxDetectors; i++)
- {
- float pos = afStepSize * i;
- //East detectors (X+)
- CreateWallDetector(pos,filename,asEntity,EAST, i);
- //West detectors (X-)
- CreateWallDetector(pos,filename,asEntity,WEST, i);
- //North detectors (Z+)
- CreateWallDetector(pos,filename,asEntity,NORTH, i);
- //South detectors (Z-)
- CreateWallDetector(pos,filename,asEntity,SOUTH, i);
- }
- //Calculate the min detectors
- @RayCastCondition = @rccMatchboxInit;
- SetMinDir(NORTH); SetMinDir(SOUTH); SetMinDir(EAST); SetMinDir(WEST);
- @RayCastCondition = @rccWall;
- }
- //Create a single wall detector
- void CreateWallDetector(float afAmt, string &in asFileName, string &in asAttachBase, Direction dir, int alIndex)
- {
- string dname = DirectionPrefix(dir) + alIndex;
- AttachProp(asAttachBase,dname,asFileName, Xcomp(dir) * afAmt, Ycomp(dir) * afAmt, Zcomp(dir) * afAmt);
- }
- //Fixed variant of AddAttachedPropToProp
- void AttachProp(string &in asPName,string &in asAName, string &in aFile, float afX, float afY, float afZ) { AddAttachedPropToProp(asPName,asAName,aFile,afX,afY,0,afZ,90.0f,afZ); }
- ///////////////////////////////
- //- DETECTOR INIT
- ///////////////////////////////
- ///////////////////////////////
- //+ CRATE MOTION
- ///////////////////////////////
- float TIMESTEP = 1.0f / 5.0f;
- void tmrCrateMotion(string &in asTimer)
- {
- Direction dir = GetCurrentDir();
- //Move the crate forward
- float impulse = 1.0f;
- AddPropImpulse(MATCHBOX, impulse * Xcomp(dir), impulse * Ycomp(dir), impulse * Zcomp(dir), "world");
- //Raycast forward -> Are we at the wall?
- @RayCastCondition = @rccWall;
- AddDebugMessage("RCV: " + RayCast(dir),false);
- if(RayCast(dir) <= GetMinDir(dir))
- {
- AddDebugMessage("At end of path. Picking new direction.",false);
- SetCurrentDir(SelectBestDirection(dir));
- }
- AddTimer(asTimer,TIMESTEP,"tmrCrateMotion");
- }
- //Select the best direction by seeing which way has the longest distance box can move (excluding where box came from)
- Direction SelectBestDirection(Direction oldDirection)
- {
- //Get a collection of directions the box can move in
- Direction[] newDirections = GetNewDirections(oldDirection);
- //Assume first defined direction is best for now
- Direction bestDirection = newDirections[0];
- int bestValue = RayCast(newDirections[0]);
- //Look through all remaining possible directions to pick best path
- for(uint i = 1; i<newDirections.length(); i++)
- {
- int newValue = RayCast(newDirections[i]);
- if(newValue > bestValue)
- {
- //Longer path than before - this is now the best direction to move
- bestValue = newValue;
- bestDirection = newDirections[i];
- }
- }
- AddDebugMessage(DirectionPrefix(oldDirection) + " -> " + DirectionPrefix(bestDirection) + " (" + bestValue + ")",false);
- return bestDirection;
- }
- //Get all the directions the box can move excluding where the box came from
- Direction[] GetNewDirections(Direction oldDirection)
- {
- switch(oldDirection)
- {
- case NORTH: return DS03;
- case SOUTH: return DS04;
- case EAST: return DS01;
- case WEST: return DS02;
- }
- return DS00;
- }
- Direction[] DS00 = {NORTH, SOUTH, EAST, WEST};
- Direction[] DS01 = {NORTH, SOUTH, EAST};
- Direction[] DS02 = {NORTH, SOUTH, WEST};
- Direction[] DS03 = {NORTH, EAST, WEST};
- Direction[] DS04 = {SOUTH, EAST, WEST};
- ///////////////////////////////
- //- CRATE MOTION
- ///////////////////////////////
- ///////////////////////////////
- //+ RAY CASTING
- ///////////////////////////////
- //Returns how many ray segments in the given direction there are until a collision occurrs
- int RayCast(Direction dir)
- {
- string pfx = DirectionPrefix(dir);
- int i =0;
- for(; GetEntityExists(pfx+i); i++)
- if(RayCastCondition(pfx+i)) return i;
- return i;
- }
- //used to determine if the raytrace should continue
- funcdef bool RAYCASTCONDITION(string &in);
- RAYCASTCONDITION @RayCastCondition = @rccWall;
- //returns true if ray segment collides with a wall (used for detector)
- bool rccWall(string &in asRaySegment)
- {
- //i<100 to get around missing wall peices.
- for(int i = 1; i < 100; i++)
- if(GetEntitiesCollide(WALL+i,asRaySegment)) return true;
- return false;
- }
- //returns true if ray segment doesn't collide with the matchbox (used in init)
- bool rccMatchboxInit(string &in asRaySegment)
- { return !GetEntitiesCollide(MATCHBOX,asRaySegment); }
- ///////////////////////////////
- //- RayCasting
- ///////////////////////////////
- ///////////////////////////////
- //+ DIRECTION ENUM
- ///////////////////////////////
- enum Direction
- {
- NORTH,
- SOUTH,
- EAST,
- WEST
- }
- //Prefix of a given direction
- string DirectionPrefix(Direction dir)
- {
- switch(dir)
- {
- case NORTH: return "N";
- case SOUTH: return "S";
- case EAST: return "E";
- case WEST: return "W";
- }
- AddDebugMessage("Error: Unknown direction error",false);
- return "?";
- }
- //Get/Set the min value for a direction
- void SetMinDir(Direction dir)
- {
- string vn = "MIN_" + DirectionPrefix(dir);
- SetLocalVarInt(vn,RayCast(dir));
- AddDebugMessage(vn + ":" + GetLocalVarInt(vn),false);
- }
- int GetMinDir(Direction dir)
- {
- return GetLocalVarInt("MIN_" + DirectionPrefix(dir));
- }
- //Get/Set current direction
- void SetCurrentDir(Direction dir)
- {
- switch(dir)
- {
- case NORTH: SetLocalVarInt("CDIR",1); break;
- case SOUTH: SetLocalVarInt("CDIR",2); break;
- case EAST: SetLocalVarInt("CDIR",3); break;
- case WEST: SetLocalVarInt("CDIR",4); break;
- }
- }
- Direction GetCurrentDir()
- {
- switch(GetLocalVarInt("CDIR"))
- {
- case 1: return NORTH;
- case 2: return SOUTH;
- case 3: return EAST;
- case 4: return WEST;
- }
- return NORTH;
- }
- //Components of direction
- float Xcomp(Direction dir) { switch(dir) { case EAST: return 1.0f; case WEST: return -1.0f; } return 0.0f; }
- float Ycomp(Direction dir) { return 0.0f; }
- float Zcomp(Direction dir) { switch(dir) { case NORTH: return 1.0f; case SOUTH: return -1.0f; } return 0.0f; }
- ///////////////////////////////
- //- DIRECTION ENUM
- ///////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement