public void Start() { if (world == null) { world = World.mainWorld; } thingDoing = new ThingDoing(TypeOfThingDoing.Standing, null); genome = new Genome(GetBaseGenome()); food = genome["baseHunger"]; stamina = genome["baseStamina"]; maxStamina = genome["maxStamina"]; maxFood = genome["maxFood"]; for (int i = 0; i < actionWeights.Length; i++) { TypeOfThingDoing typeOfThing = (TypeOfThingDoing)i; float maxValue = 10.0f; if (IsImportant(typeOfThing, ref maxValue)) { isImportant[i] = true; importantMaxValues[i] = maxValue; } else { isImportant[i] = false; } actionBaseWeights[i] = GetBaseWeight(typeOfThing); } }
/* * public override void UpdateBehavior(ref ThingDoing curDoing) * { * * if (curDoing == null) * { * curDoing = new ThingDoing(TypeOfThingDoing.Searching, null); * } * * if (food < wantToFindFoodThresh && curDoing.typeOfThing != TypeOfThingDoing.Chasing && curDoing.typeOfThing != TypeOfThingDoing.Searching) * { * curDoing = new ThingDoing(TypeOfThingDoing.Searching); * } * * if (food >= wantToFindFoodThresh && curDoing.typeOfThing != TypeOfThingDoing.RunningAway) * { * curDoing = new ThingDoing(TypeOfThingDoing.Standing); * } * * * BlocksPlayer[] players = FindObjectsOfType<BlocksPlayer>(); * * foreach (BlocksPlayer player in players) * { * if (Vector3.Distance(player.transform.position, transform.position) < 10.0f) * { * curDoing = new ThingDoing(TypeOfThingDoing.RunningAway, new ThingDoingTarget(player.GetComponent<MovingEntity>())); * } * } * * MovingEntity self = GetComponent<MovingEntity>(); * if (curDoing.typeOfThing == TypeOfThingDoing.Chasing) * { * if (curDoing.target.entity == null) * { * pathingTarget = curDoing.target.block; * } * else * { * pathingTarget = LVector3.FromUnityVector3(curDoing.target.entity.transform.position); * } * * * if (pathingTarget.BlockV != Example.FlowerWithNectar) * { * curDoing = new ThingDoing(TypeOfThingDoing.Searching, null); * } * else * { * float myDist = LVector3.CityBlockDistance(LVector3.FromUnityVector3(transform.position), pathingTarget); * // found it, eat it * if (myDist < 4) * { * DidEatObject(pathingTarget, 1.0f); * world[pathingTarget] = (int)Example.Flower; * curDoing = new ThingDoing(TypeOfThingDoing.Searching, null); * } * // still pathing to it * else * { * UpdatePathing(); * } * } * //pathingTarget = LVector3.FromUnityVector3(FindObjectOfType<BlocksPlayer>().transform.position); * } * else if (curDoing.typeOfThing == TypeOfThingDoing.RunningAway) * { * if (curDoing.target.entity == null) * { * pathingTarget = curDoing.target.block; * } * else * { * pathingTarget = LVector3.FromUnityVector3(curDoing.target.entity.transform.position); * } * } * else if (curDoing.typeOfThing == TypeOfThingDoing.Searching) * { * } * else if (curDoing.typeOfThing == TypeOfThingDoing.Sitting) * { * * } * else if (curDoing.typeOfThing == TypeOfThingDoing.Socializing) * { * * } * else if (curDoing.typeOfThing == TypeOfThingDoing.Standing) * { * GetComponent<CrocodileDoggy>().SetSpeed(0.0f); * self.desiredMove = Vector3.zero; * } * else if (curDoing.typeOfThing == TypeOfThingDoing.Wandering) * { * * } * } * */ public override ThingDoing UpdateBehavior(TypeOfThingDoing newTypeOfThingDoing) { ThingDoing result = null; if (assignment == SisterAssignment.StayWithMother) { result = new ThingDoing(TypeOfThingDoing.GoingTo, new ThingDoingTarget(mother.GetComponent <MovingEntity>())); } else if (assignment == SisterAssignment.StayWithChampion) { result = new ThingDoing(TypeOfThingDoing.GoingTo, new ThingDoingTarget(champion.GetComponent <MovingEntity>())); } else if (assignment == SisterAssignment.Forage) { result = new ThingDoing(TypeOfThingDoing.Gathering, new ThingDoingTarget(new BlockValue[] { Example.Leaf, Example.Trunk, Example.Flower })); } else if (assignment == SisterAssignment.KeepWatch) { result = new ThingDoing(TypeOfThingDoing.Standing, null); } else { Debug.LogWarning("unknown sister assignment " + assignment); result = new ThingDoing(newTypeOfThingDoing, null); } if (result.typeOfThing == thingDoing.typeOfThing) { // don't modify it if valid blocks matches (this keeps a found position if there is one when foraging) if (result.target != null && result.target.validBlocks != null) { if (thingDoing.target == null || thingDoing.target.validBlocks == null || thingDoing.target.validBlocks.Length != result.target.validBlocks.Length) { return(result); } else { for (int i = 0; i < result.target.validBlocks.Length; i++) { if (thingDoing.target.validBlocks[i] != result.target.validBlocks[i]) { return(result); } } return(thingDoing); } } return(thingDoing); } else { return(result); } }
public void Update() { this.typeOfThingDoing = this.thingDoing.typeOfThing; if (world == null) { world = World.mainWorld; if (world == null) // not initialized yet, wait { return; } } if (updateAction.Do()) { //Debug.Log("updating action"); float totalWeight = 0.0f; for (int i = 0; i < actionWeights.Length; i++) { actionWeights[i] = actionBaseWeights[i] + GetWeight((TypeOfThingDoing)i); if (isImportant[i]) { actionWeights[i] = zeroOneThing(actionWeights[i], importantMaxValues[i]); } totalWeight += actionWeights[i]; } if (totalWeight <= 0.0f) { totalWeight = 1.0f; } // randomly sample proportional to weights float randVal = Random.value; float cumulSum = 0.0f; int chosenThing = 0; for (int i = 0; i < (int)TypeOfThingDoing.MaxValue; i++) { cumulSum += actionWeights[i] / totalWeight; if (randVal <= cumulSum) { chosenThing = i; break; } } int curAct = (int)thingDoing.typeOfThing; float curWeight = actionWeights[curAct]; float chosenWeight = actionWeights[chosenThing]; float diff = curWeight - chosenWeight; // if current is much more likely, don't change if (diff > 1.0f) { } // otherwise, change with diff pr (if diff < 0 this means always change) else/* if (diff < 0) * { * TypeOfThingDoing chosenThingDoing = (TypeOfThingDoing)chosenThing; * thingDoing = UpdateBehavior(chosenThingDoing); * if (thingDoing.typeOfThing == TypeOfThingDoing.GettingFood) * { * OnSearchForFood(out lookingForBlock, out blockLookingFor); * } * } * else if (Random.value < diff)*/ { TypeOfThingDoing chosenThingDoing = (TypeOfThingDoing)chosenThing; ThingDoing prevThingDoing = thingDoing; thingDoing = UpdateBehavior(chosenThingDoing); if (thingDoing != prevThingDoing) { iNeedToPathfindAgain = true; } if (thingDoing.typeOfThing == TypeOfThingDoing.GettingFood) { OnSearchForFood(out lookingForBlock, out blockLookingFor); } } } if (thingDoing.typeOfThing == TypeOfThingDoing.GettingFood || thingDoing.typeOfThing == TypeOfThingDoing.RunningAway || thingDoing.typeOfThing == TypeOfThingDoing.Gathering || thingDoing.typeOfThing == TypeOfThingDoing.GoingTo) { UpdatePathing(); } else if (thingDoing.typeOfThing == TypeOfThingDoing.Socializing) { thingDoing.typeOfThing = TypeOfThingDoing.Wandering; } else if (thingDoing.typeOfThing == TypeOfThingDoing.Standing) { GetComponent <MovingEntity>().desiredMove = Vector3.zero; } else if (thingDoing.typeOfThing == TypeOfThingDoing.Wandering) { if (updateWander.Do()) { //int randVal = Random.Range(0, 5); Vector3[] options = new Vector3[] { Vector3.zero, Vector3.forward, Vector3.right, Vector3.left, Vector3.back }; Vector3 desiredMove = options[Random.Range(0, options.Length)]; MovingEntity me = GetComponent <MovingEntity>(); me.desiredMove = Vector3.zero; me.jumping = false; RaycastResults blockStandingOn = me.BlockStandingOn(); if (blockStandingOn != null && desiredMove != Vector3.zero) { LVector3 myPos = blockStandingOn.hitBlock + new LVector3(0, 1, 0); LVector3 nextPos = myPos + new LVector3((long)desiredMove.x, (long)desiredMove.y, (long)desiredMove.z); LVector3 belowNextPos = nextPos + new LVector3(0, -1, 0); LVector3 aboveNextPos = nextPos + new LVector3(0, 1, 0); bool needsToJump = false; bool okayToMove = false; bool needsToShift = false; // we need to hop up if (nextPos.Block != Example.Air) { // we can hop up if (aboveNextPos.Block == Example.Air) { okayToMove = true; needsToJump = true; } // we can't hop up else { } } // we won't run into anything and can walk there else { // going down if (belowNextPos.Block == Example.Air) { LVector3 belowBelowNextPos = belowNextPos + new LVector3(0, -1, 0); // too far to fall, don't do it if (belowBelowNextPos.Block == Example.Air) { } // down stairs, that's fine else { okayToMove = true; } } // just horizontal, that's fine else { okayToMove = true; } } me.jumping = needsToJump; me.usingShift = needsToShift; if (okayToMove) { me.desiredMove = desiredMove; } } } } }
public void UpdatePathing() { ////// new temp stuff MovingEntity body = GetComponent <MovingEntity>(); //pathingTarget = LVector3.FromUnityVector3(FindObjectOfType<BlocksPlayer>().transform.position); /* * // find position on ground below player and path to that instead * int goDownAmount = 10; // don't get into infinite loop, give up eventually * while (pathingTarget.BlockV == BlockValue.Air && goDownAmount > 0) * { * pathingTarget = pathingTarget - new LVector3(0, 1, 0); * goDownAmount--; * } * pathingTarget += new LVector3(0, 2, 0); */ ////// pathingTarget = LVector3.Invalid; if (thingDoing != null) { if (thingDoing.target != null) { if (thingDoing.target.entity != null) { pathingTarget = LVector3.FromUnityVector3(thingDoing.target.entity.transform.position); iNeedToPathfindAgain = true; } else if (thingDoing.target.block != LVector3.Invalid) { pathingTarget = thingDoing.target.block; //Debug.Log("going to pathing target with block in thing doing of " + pathingTarget); } } } if (curPath == null) { iNeedToPathfindAgain = true; } if (pathingTarget == LVector3.Invalid) { body.desiredMove = Vector3.zero; } if (PhysicsUtils.millis() - lastPathfind > 1000.0 / pathfindsPerSecond && frameUpdatedLast != Time.frameCount && iNeedToPathfindAgain) // offset so everyone isn't aligned on the same frame { LVector3 myPos = LVector3.FromUnityVector3(transform.position); LVector3 foundThing; /* * if (Search(out foundThing)) * { * // found it, is it closer? * if (pathingTarget == LVector3.Invalid || LVector3.CityBlockDistance(foundThing, myPos) < LVector3.CityBlockDistance(pathingTarget, myPos)) * { * // if so, go to it instead * ThingDoing newThingDoing = new ThingDoing(thingDoing.typeOfThing, new ThingDoingTarget(foundThing)); * // copy over valid blocks for future reference * if (thingDoing != null && thingDoing.target != null) * { * newThingDoing.target.validBlocks = thingDoing.target.validBlocks; * } * thingDoing = newThingDoing; * pathingTarget = foundThing; * } * //Debug.Log("found thing when looking"); * } * else * { * // did not find * //Debug.Log("did not find thing when looking"); * //Debug.Log("did not find thing in " + steps + " steps"); * } */ frameUpdatedLast = Time.frameCount; //Debug.Log("updating pathing"); RaycastResults blockStandingOn; bool lookingForBlocks = false; if (thingDoing != null && thingDoing.target != null && thingDoing.target.entity == null && thingDoing.target.block == LVector3.Invalid && thingDoing.target.validBlocks != null) { lookingForBlocks = true; } if (pathingTarget != LVector3.Invalid || lookingForBlocks) { if (PhysicsUtils.RayCastAlsoHitWater(body.transform.position, -Vector3.up, 20.0f, out blockStandingOn)) { // if we are using shift and standing over an empty block, but our feet are on a neighboring block, use that neighboring block for pathfinding instead if (blockStandingOn != LVector3.Invalid) { myPos = blockStandingOn.hitBlock + new LVector3(0, blocksHeight, 0); } //LVector3 playerPos = LVector3.FromUnityVector3(pathingTarget.transform.position); bool iShouldJump; if (thingDoing.typeOfThing == TypeOfThingDoing.RunningAway) { PhysicsUtils.PathfindAway(blocksHeight, ref curPath, out iShouldJump, myPos, pathingTarget, 100); } else { //// new stuff bool pathingSuccess = false; PathingRegionPos resPath = null; if (lookingForBlocks) { resPath = PathingChunk.PathindToResource(World.mainWorld, myPos, GetComponent <MovingEntity>().reachRange, thingDoing.target.validBlocks, new MobilityCriteria(1, 1, blocksHeight, 1), out pathingSuccess, out blockWeCanSeeOnceWeGetThere, verbose: world.blocksWorld.verbosePathing); if (resPath != null) { pathingTarget = new LVector3(resPath.wx, resPath.wy, resPath.wz); thingDoing = new ThingDoing(thingDoing.typeOfThing, new ThingDoingTarget(pathingTarget, thingDoing.target.validBlocks)); } } else { resPath = BlocksPathing.Pathfind(World.mainWorld, myPos, pathingTarget, 1, 1, blocksHeight, 1, out pathingSuccess, verbose: false); } iShouldJump = false; if (resPath != null) { curPath = (new PathingResult(resPath)).GetPathNode(); iNeedToPathfindAgain = false; //Debug.Log("got path with next pos " + curPath.pos + " also, my pos is " + myPos + " and pathing target is " + pathingTarget); if (curPath.nextNode != null && curPath.nextNode.pos.y > curPath.pos.y) { iShouldJump = true; } if (curPath.nextNode != null) { //curPath = curPath.nextNode; } } else { curPath = null; iNeedToPathfindAgain = true; } ///// /// // old thing: //PhysicsUtils.Pathfind(blocksHeight, ref curPath, out iShouldJump, myPos, pathingTarget+new LVector3(0,1,0), 100); } if (curPath != null) { if (curPath.nextNode == null) { //Debug.Log("curPath = " + curPath.pos + " myPos = " + myPos + " next null"); } else { //Debug.Log("curPath = " + curPath.pos + " myPos = " + myPos + " nextPath = " + curPath.nextNode.pos); } } if (iShouldJump) { body.jumping = true; } } else { //Debug.Log("falling far, cannot pathfind"); } } lastPathfind = PhysicsUtils.millis(); } if (pathingTarget == LVector3.Invalid) { //Debug.Log("has invalid pathing target?"); iNeedToPathfindAgain = true; } body.desiredMove = Vector3.zero; Vector3 targetPos = transform.position; if (curPath != null && pathingTarget != LVector3.Invalid) { /* // dani commented this out recently * LVector3 myPos = LVector3.FromUnityVector3(transform.position); * RaycastResults blockStandingOn; * if (PhysicsUtils.RayCastAlsoHitWater(body.transform.position, -Vector3.up, 20.0f, out blockStandingOn)) * { * // if we are using shift and standing over an empty block, but our feet are on a neighboring block, use that neighboring block for pathfinding instead * myPos = blockStandingOn.hitBlock + new LVector3(0, blocksHeight, 0); * } * LVector3 myPosBeforeJump = myPos - new LVector3(0, 1, 0); * LVector3 myPosBeforeFall = myPos + new LVector3(0, 1, 0); */ //if (curPath.prevNode != null && (myPos == curPath.prevNode.pos || myPosBeforeJump == curPath.prevNode.pos)) //{ //} //else /* * PathNode closest = curPath; * float closestDist = LVector3.EuclideanDistance(closest.pos, myPos); * PathNode curTmp = closest; * while(curTmp.prevNode != null) * { * curTmp = curTmp.prevNode; * float tmpDist = LVector3.EuclideanDistance(curTmp.pos, myPos); * if (tmpDist < closestDist) * { * closest = curTmp; * closestDist = tmpDist; * } * } * curTmp = curPath; * while (curTmp.nextNode != null) * { * curTmp = curTmp.nextNode; * float tmpDist = LVector3.EuclideanDistance(curTmp.pos, myPos); * if (tmpDist < closestDist) * { * closest = curTmp; * closestDist = tmpDist; * } * } * * if (closest.pos == myPos) * { * if (closest.nextNode == null) * { * Debug.Log("reached end of path"); * } * else * { * curPath = closest.nextNode; * } * } * else * { * curPath = closest; * }*/ /* // dani commented this out recently * if (curPath.nextNode != null && (myPos == curPath.nextNode.pos || myPosBeforeJump == curPath.nextNode.pos || myPosBeforeFall == curPath.nextNode.pos)) * { * curPath = curPath.nextNode; * } * else if (myPos == curPath.pos || myPosBeforeJump == curPath.pos || myPosBeforeFall == curPath.pos) * { * if (curPath.nextNode != null) * { * curPath = curPath.nextNode; * } * } * * * LVector3 targetBlock = curPath.pos; * if (targetBlock.y == LVector3.FromUnityVector3(transform.position).y) * { * //body.usingShift = true; * body.usingShift = false; * } * else * { * body.usingShift = false; * } * if (targetBlock.y > myPos.y) * { * body.jumping = true; * } * else * { * body.jumping = false; * } * targetPos = targetBlock.BlockCentertoUnityVector3(); * body.SetAbsoluteDesiredMove((targetPos - transform.position).normalized); */ Vector3 dirToMove; bool pushedOffPath; curPath = curPath.GetCurNode(transform.position, out body.jumping, out dirToMove, out pushedOffPath); body.SetAbsoluteDesiredMove(dirToMove); if (pushedOffPath) { //Debug.Log("pushed off path"); //iNeedToPathfindAgain = true; } if (curPath.nextNode != null) { //Debug.Log("got cur path " + curPath.pos + " with jumping " + body.jumping + " and dir to move " + dirToMove + " and next " + curPath.nextNode.pos + " and pushed off path " + pushedOffPath); } else { //Debug.Log("got cur path " + curPath.pos + " with jumping " + body.jumping + " and dir to move " + dirToMove + " and no next and pushed off path " + pushedOffPath); } BlockValue blockWeAreGoingTo = blockWeCanSeeOnceWeGetThere.BlockV; if (!DesiredBlock(blockWeAreGoingTo) && thingDoing != null && thingDoing.target != null && thingDoing.target.entity == null) { Debug.Log("rip someone took my block , my block is now " + World.BlockToString(blockWeAreGoingTo)); curPath = null; pathingTarget = LVector3.Invalid; } else { float myDist = LVector3.CityBlockDistance(LVector3.FromUnityVector3(transform.position), pathingTarget); // found it, eat it if (myDist <= 2) { //Debug.Log("got to desired block"); if (thingDoing != null && thingDoing.typeOfThing == TypeOfThingDoing.GettingFood) { OnReachFoodBlock(blockWeCanSeeOnceWeGetThere); } else if (thingDoing != null && thingDoing.typeOfThing == TypeOfThingDoing.Gathering) { OnReachBlockToGather(blockWeCanSeeOnceWeGetThere); } /* * DidEatObject(pathingTarget, 1.0f); * world[pathingTarget] = (int)Example.Flower; */ //this.thingDoing = new ThingDoing(TypeOfThingDoing.GettingFood, null); if (thingDoing != null && thingDoing.target != null) { this.thingDoing = new ThingDoing(thingDoing.typeOfThing, new ThingDoingTarget(thingDoing.target.validBlocks)); } else if (thingDoing != null) { this.thingDoing = new ThingDoing(thingDoing.typeOfThing, null); } curPath = null; pathingTarget = LVector3.Invalid; body.jumping = false; iNeedToPathfindAgain = true; } // still pathing to it else { } } } }