From: Keith F. <ven...@us...> - 2003-06-14 17:31:50
|
Update of /cvsroot/planeshift/planeshift/src/npcclient In directory sc8-pr-cvs1:/tmp/cvs-serv31770 Modified Files: npcclient.h npcclient.cpp npcbehave.h npcbehave.cpp npc.h npc.cpp Log Message: Committed compile fixes for superclient also. Superclient will now read in regions, which are polygons of arbitrary complexity, and will detect when an npc has move outside of the specified region with the <move> command. Index: npcclient.h =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/npcclient/npcclient.h,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** npcclient.h 9 Jun 2003 06:39:35 -0000 1.7 --- npcclient.h 14 Jun 2003 17:31:47 -0000 1.8 *************** *** 70,73 **** --- 70,74 ---- csString name; LocationVector locs; + bool region; bool operator==(LocationType& other) { return name==other.name; } *************** *** 76,79 **** --- 77,81 ---- bool Load(iDocumentNode *node); + bool CheckWithinBounds(csVector3& pos); }; *************** *** 138,141 **** --- 140,149 ---- */ bool Locate(const char *loctype,csVector3& pos,float& rotation,float range); + + /** + * This function handles the searching for the specified region name + * so that other functions can refer to the region directly. + */ + LocationType *FindRegion(const char *regname); /** Index: npcclient.cpp =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/npcclient/npcclient.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** npcclient.cpp 9 Jun 2003 06:39:35 -0000 1.8 --- npcclient.cpp 14 Jun 2003 17:31:47 -0000 1.9 *************** *** 276,282 **** // This is a widget so read it's factory to create it. ! if ( strcmp( node->GetValue(), "loctype" ) == 0 ) { LocationType *loctype = new LocationType; if (loctype->Load(node)) { --- 276,288 ---- // This is a widget so read it's factory to create it. ! if ( strcmp( node->GetValue(), "loctype" ) == 0 || ! strcmp( node->GetValue(), "region" ) == 0) { LocationType *loctype = new LocationType; + if (strcmp( node->GetValue(), "region" ) == 0) + loctype->region = true; + else + loctype->region = false; + if (loctype->Load(node)) { *************** *** 361,364 **** --- 367,383 ---- } + LocationType *psNPCClient::FindRegion(const char *regname) + { + LocationType key; + key.name = regname; + + LocationType *found = loctypes.Find(&key); + if (found && found->region==true) + { + return found; + } + return NULL; + } + bool psNPCClient::Locate(const char *loctype,csVector3& pos,float& rotation,float range) { *************** *** 367,371 **** LocationType *found = loctypes.Find(&key); ! if (found) { float min_range = 10000000; --- 386,390 ---- LocationType *found = loctypes.Find(&key); ! if (found && found->region==false) { float min_range = 10000000; *************** *** 450,451 **** --- 469,508 ---- return true; } + + bool LocationType::CheckWithinBounds(csVector3& p) + { + if (!region) + return false; + + // Thanks to http://astronomy.swin.edu.au/~pbourke/geometry/insidepoly/ + // for this example code. + int counter = 0; + int i,N=locs.Length(); + float xinters; + csVector3 p1,p2; + + p1 = locs[0]->pos; + for (i=1; i<=N; i++) + { + p2 = locs[i % N]->pos; + if (p.z > MIN(p1.z,p2.z)) + { + if (p.z <= MAX(p1.z,p2.z)) + { + if (p.x <= MAX(p1.x,p2.x)) + { + if (p1.z != p2.z) + { + xinters = (p.z-p1.z)*(p2.x-p1.x)/(p2.z-p1.z)+p1.x; + if (p1.x == p2.x || p.x <= xinters) + counter++; + } + } + } + } + p1 = p2; + } + + return (counter % 2 != 0); + } + Index: npcbehave.h =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/npcclient/npcbehave.h,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** npcbehave.h 13 Jun 2003 17:34:35 -0000 1.8 --- npcbehave.h 14 Jun 2003 17:31:47 -0000 1.9 *************** *** 37,40 **** --- 37,41 ---- class NPC; class EventManager; + class BehaviorSet; /** *************** *** 56,60 **** return reactions.Find(key); } ! void DeepCopy(ReactionSet& other); }; --- 57,61 ---- return reactions.Find(key); } ! void DeepCopy(ReactionSet& other,BehaviorSet& behaviors,BinaryTree<Perception>& perceptions); }; *************** *** 116,120 **** void Advance(csTicks delta,NPC *npc,EventManager *eventmgr); void ResumeScript(NPC *npc,EventManager *eventmgr,Behavior *which); ! void FirePerception(Perception *fired); Behavior *GetCurrentBehavior() --- 117,121 ---- void Advance(csTicks delta,NPC *npc,EventManager *eventmgr); void ResumeScript(NPC *npc,EventManager *eventmgr,Behavior *which); ! void FirePerception(const char *perception,NPC *npc,EventManager *eventmgr); Behavior *GetCurrentBehavior() *************** *** 163,167 **** const char *GetName() { return name; } ! void Trigger(NPC *who); bool operator==(Perception& other) --- 164,168 ---- const char *GetName() { return name; } ! void Trigger(NPC *who,EventManager *eventmgr); bool operator==(Perception& other) *************** *** 205,209 **** bool Load(iDocumentNode *node,bool top_level=true); ! void Advance(csTicks delta); float CurrentNeed() { return current_need; } --- 206,210 ---- bool Load(iDocumentNode *node,bool top_level=true); ! void Advance(csTicks delta,NPC *npc,EventManager *eventmgr); float CurrentNeed() { return current_need; } *************** *** 212,215 **** --- 213,218 ---- void CommitAdvance() { current_need = new_need; } + void ApplyNeedDelta(float delta_desire) + { current_need += delta_desire; } void SetActive(bool flag) { is_active = flag; } *************** *** 246,250 **** bool Load(iDocumentNode *node,BehaviorSet& behaviors,BinaryTree<Perception>& perceptions); ! virtual void React(NPC *who); bool operator==(Reaction& other) --- 249,253 ---- bool Load(iDocumentNode *node,BehaviorSet& behaviors,BinaryTree<Perception>& perceptions); ! virtual void React(NPC *who,EventManager *eventmgr); bool operator==(Reaction& other) *************** *** 275,278 **** --- 278,282 ---- public: virtual bool Run(NPC *npc,EventManager *eventmgr)=0; + virtual void Advance(float timedelta,NPC *npc,EventManager *eventmgr) { }; virtual bool CompleteOperation(NPC *npc,EventManager *eventmgr) { return true; } virtual bool Load(iDocumentNode *node)=0; *************** *** 282,285 **** --- 286,291 ---- }; + class LocationType; + /** * Moving entails a velocity vector and an animation action. *************** *** 290,297 **** --- 296,307 ---- csVector3 vel; csString action; + csString region; + LocationType *rgn; + public: MoveOperation() { vel.Set(0,0,0); } virtual bool Run(NPC *npc,EventManager *eventmgr); + virtual void Advance(float timedelta,NPC *npc,EventManager *eventmgr); virtual bool Load(iDocumentNode *node); virtual ScriptOperation *MakeCopy(); *************** *** 312,315 **** --- 322,326 ---- virtual bool Run(NPC *npc,EventManager *eventmgr); + virtual void Advance(float timedelta,NPC *npc,EventManager *eventmgr); virtual bool Load(iDocumentNode *node); virtual ScriptOperation *MakeCopy(); Index: npcbehave.cpp =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/npcclient/npcbehave.cpp,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** npcbehave.cpp 14 Jun 2003 17:28:41 -0000 1.9 --- npcbehave.cpp 14 Jun 2003 17:31:47 -0000 1.10 *************** *** 108,111 **** --- 108,127 ---- } + void NPCType::FirePerception(const char *perception,NPC *npc,EventManager *eventmgr) + { + Perception temp(perception); + Perception *p; + p = perceptions.Find(&temp); + if (p) + { + p->Trigger(npc,eventmgr); + } + else + { + printf("NPCType %s doesn't have any reaction to %s perceptions.\n", + (const char *)name,perception); + } + } + void NPCType::DeepCopy(NPCType& other) { *************** *** 124,129 **** behaviors.DeepCopy(other.behaviors); ! reactions.DeepCopy(other.reactions); ! } --- 140,144 ---- behaviors.DeepCopy(other.behaviors); ! reactions.DeepCopy(other.reactions,behaviors,perceptions); } *************** *** 147,151 **** for (b = iter.First(); b; b = (next) ? next : ++iter) { ! b->Advance(delta); if (last_need && b->NewNeed() > last_need) // the advance causes re-ordering { --- 162,166 ---- for (b = iter.First(); b; b = (next) ? next : ++iter) { ! b->Advance(delta,npc,eventmgr); if (last_need && b->NewNeed() > last_need) // the advance causes re-ordering { *************** *** 190,193 **** --- 205,211 ---- b->StartScript(npc,eventmgr); } + else // same need as last time + { + } } } *************** *** 224,228 **** } ! void ReactionSet::DeepCopy(ReactionSet& other) { BinaryTreeIterator<Reaction> riter(&other.reactions,BinaryTreeIterator<Reaction>::ITER_PREORDER); --- 242,246 ---- } ! void ReactionSet::DeepCopy(ReactionSet& other,BehaviorSet& behaviors,BinaryTree<Perception>& perceptions) { BinaryTreeIterator<Reaction> riter(&other.reactions,BinaryTreeIterator<Reaction>::ITER_PREORDER); *************** *** 230,234 **** for (r = riter.First(); r; r = ++riter) { ! r2 = new Reaction(*r); reactions.Add(r2); // worry about subscriptions later } --- 248,252 ---- for (r = riter.First(); r; r = ++riter) { ! r2 = new Reaction(*r,behaviors,perceptions); reactions.Add(r2); // worry about subscriptions later } *************** *** 266,270 **** } p->Subscribe(this); ! return true; } --- 284,289 ---- } p->Subscribe(this); ! perception = p; ! return true; } *************** *** 276,290 **** Perception temp( other.perception->GetName() ); perception = perceptions.Find(&temp); affected = behaviors.Find(other.affected->GetName()); } ! void Reaction::React(NPC *who) { } ! void Perception::Trigger(NPC *who) { for (int i=0; i<listeners.Length(); i++) ! listeners[i]->React(who); } --- 295,319 ---- Perception temp( other.perception->GetName() ); perception = perceptions.Find(&temp); + if (!perception) + { + printf("Error in Reaction::DeepCopy!\n"); + } + perception->Subscribe(this); + affected = behaviors.Find(other.affected->GetName()); } ! void Reaction::React(NPC *who,EventManager *eventmgr) { + printf("Adding %1.1f need to behavior %s for npc %s.\n", + delta_desire, affected->GetName(), who->GetEntity()->GetName() ); + + affected->ApplyNeedDelta(delta_desire); } ! void Perception::Trigger(NPC *who,EventManager *eventmgr) { for (int i=0; i<listeners.Length(); i++) ! listeners[i]->React(who,eventmgr); } *************** *** 463,473 **** } ! void Behavior::Advance(csTicks delta) { float d = .001 * delta; if (is_active) new_need = current_need - (d * need_decay_rate); else new_need = current_need + (d * need_growth_rate); } --- 492,507 ---- } ! void Behavior::Advance(csTicks delta,NPC *npc,EventManager *eventmgr) { float d = .001 * delta; if (is_active) + { new_need = current_need - (d * need_decay_rate); + sequence[current_step]->Advance(d,npc,eventmgr); + } else + { new_need = current_need + (d * need_growth_rate); + } } *************** *** 508,511 **** --- 542,546 ---- vel.z = node->GetAttributeValueAsFloat("z"); action = node->GetAttributeValue("anim"); + region = node->GetAttributeValue("region"); return true; } *************** *** 516,519 **** --- 551,556 ---- op->vel = vel; op->action = action; + op->region = region; + return op; } *************** *** 522,528 **** { printf("MoveOp "); ! return true; } --- 559,619 ---- { printf("MoveOp "); ! ! rgn = npcclient->FindRegion(region); ! if (!rgn) ! { ! printf("Region %s could not be found for npc %s.\n", ! (const char *)region, ! npc->GetEntity()->GetName()); ! return false; // this halts this script ! } ! ! csRef<iPcLinearMovement> linmove = CEL_QUERY_PROPCLASS(npc->GetEntity()->GetPropertyClassList(), ! iPcLinearMovement); ! ! csRef<iPcMesh> pcmesh = CEL_QUERY_PROPCLASS(npc->GetEntity()->GetPropertyClassList(), ! iPcMesh); ! ! // Get Going at the right velocity ! csVector3 velvector(-vel); ! linmove->SetVelocity(velvector); ! ! // SetAction animation for the mesh also, so it looks right ! pcmesh->SetAction(action); ! ! //now persist ! csRef<iDataBuffer> data = linmove->GetDRData(); ! npcclient->GetNetworkMgr()->QueueDRData(npc->GetEntity()->GetID(),data); ! ! // Note no "wake me up when over" event here. ! // Move just keeps moving the same direction until pre-empted by something else. ! return false; } + void MoveOperation::Advance(float timedelta,NPC *npc,EventManager *eventmgr) + { + printf("MoveTo Advance %1.2f\n",timedelta); + + csRef<iPcLinearMovement> linmove = CEL_QUERY_PROPCLASS(npc->GetEntity()->GetPropertyClassList(), + iPcLinearMovement); + + csVector3 pos,pos2; + float rot; + iSector * sector; + + linmove->GetLastPosition(pos,rot,sector); + linmove->ExtrapolatePosition(timedelta); + linmove->GetLastPosition(pos2,rot,sector); + + if (pos == pos2) // then stopped dead, presumably by collision + { + npc->TriggerEvent("collision",eventmgr); + } + else // check for within region bounds + { + if (!rgn->CheckWithinBounds(pos2)) + npc->TriggerEvent("out of bounds",eventmgr); + } + } *************** *** 571,575 **** // Get Going at the right velocity csVector3 velvector(0,0,-vel); ! linmove->Move(velvector); // SetAction animation for the mesh also, so it looks right --- 662,666 ---- // Get Going at the right velocity csVector3 velvector(0,0,-vel); ! linmove->SetVelocity(velvector); // SetAction animation for the mesh also, so it looks right *************** *** 599,602 **** --- 690,714 ---- } + void MoveToOperation::Advance(float timedelta,NPC *npc,EventManager *eventmgr) + { + printf("MoveTo Advance %1.2f\n",timedelta); + + csRef<iPcLinearMovement> linmove = CEL_QUERY_PROPCLASS(npc->GetEntity()->GetPropertyClassList(), + iPcLinearMovement); + + csVector3 pos,pos2; + float rot; + iSector * sector; + + linmove->GetLastPosition(pos,rot,sector); + linmove->ExtrapolatePosition(timedelta); + linmove->GetLastPosition(pos2,rot,sector); + + if (pos == pos2) // then stopped dead, presumably by collision + { + npc->TriggerEvent("collision",eventmgr); + } + } + bool MoveToOperation::CompleteOperation(NPC *npc,EventManager *eventmgr) { *************** *** 608,612 **** // Set Vel to zero again ! linmove->Move( csVector3(0,0,0) ); // Get the rot and sector here so they don't change in the SetPosition call --- 720,724 ---- // Set Vel to zero again ! linmove->SetVelocity( csVector3(0,0,0) ); // Get the rot and sector here so they don't change in the SetPosition call *************** *** 690,694 **** iPcLinearMovement); ! linmove->Rotate( csVector3(0,(angle>0)?ang_vel:-ang_vel,0) ); // Save target angle so we can jam that in on Rotate completion. --- 802,806 ---- iPcLinearMovement); ! linmove->SetRotation( csVector3(0,(angle>0)?ang_vel:-ang_vel,0) ); // Save target angle so we can jam that in on Rotate completion. *************** *** 752,756 **** iPcLinearMovement); ! linmove->Rotate( csVector3(0,(angle>0)?ang_vel:-ang_vel,0) ); csRef<iPcMesh> pcmesh = CEL_QUERY_PROPCLASS(npc->GetEntity()->GetPropertyClassList(), --- 864,868 ---- iPcLinearMovement); ! linmove->SetRotation( csVector3(0,(angle>0)?ang_vel:-ang_vel,0) ); csRef<iPcMesh> pcmesh = CEL_QUERY_PROPCLASS(npc->GetEntity()->GetPropertyClassList(), *************** *** 780,784 **** iPcLinearMovement); ! linmove->Rotate( csVector3(0,0,0) ); if (target_angle >= 0) psGameObject::SetRotationAngle(npc->GetEntity(),target_angle); --- 892,896 ---- iPcLinearMovement); ! linmove->SetRotation( csVector3(0,0,0) ); if (target_angle >= 0) psGameObject::SetRotationAngle(npc->GetEntity(),target_angle); *************** *** 878,882 **** // Set Vel to zero again ! linmove->Move( csVector3(0,0,0) ); // Get the rot and sector here so they don't change in the SetPosition call --- 990,994 ---- // Set Vel to zero again ! linmove->SetVelocity( csVector3(0,0,0) ); // Get the rot and sector here so they don't change in the SetPosition call Index: npc.h =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/npcclient/npc.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** npc.h 13 Jun 2003 17:34:36 -0000 1.6 --- npc.h 14 Jun 2003 17:31:47 -0000 1.7 *************** *** 59,62 **** --- 59,64 ---- void ResumeScript(EventManager *eventmgr,Behavior *which); + void TriggerEvent(const char *eventname,EventManager *eventmgr); + void SetActiveLocate(csVector3& pos,float rot) { active_locate_pos=pos; active_locate_angle=rot; } Index: npc.cpp =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/npcclient/npc.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** npc.cpp 31 May 2003 07:18:40 -0000 1.2 --- npc.cpp 14 Jun 2003 17:31:47 -0000 1.3 *************** *** 77,78 **** --- 77,84 ---- } + void NPC::TriggerEvent(const char *eventname,EventManager *eventmgr) + { + printf("Got event '%s'.\n",eventname); + brain->FirePerception(eventname,this,eventmgr); + } + |