001    package student;
002    
003    
004    import jade.core.AID;
005    import jade.domain.DFService;
006    import jade.domain.FIPAException;
007    import jade.domain.FIPANames;
008    import jade.domain.FIPAAgentManagement.DFAgentDescription;
009    import jade.domain.FIPAAgentManagement.ServiceDescription;
010    import jade.lang.acl.ACLMessage;
011    
012    import java.util.Iterator;
013    
014    import es.upv.dsic.gti_ia.jgomas.CMedic;
015    import es.upv.dsic.gti_ia.jgomas.CPack;
016    import es.upv.dsic.gti_ia.jgomas.CSight;
017    import es.upv.dsic.gti_ia.jgomas.CTask;
018    import es.upv.dsic.gti_ia.jgomas.Vector3D;
019    
020    public class MyMedic extends CMedic {
021            
022    
023            /**
024             * 
025             */
026            private static final long serialVersionUID = 1L;
027    
028    
029            protected void setup() {
030    
031                    super.setup();
032                    SetUpPriorities();
033    
034            }
035    
036            /////////////////////////////////////////////////////////////////////////////////////////////////////
037            // Methods to overload inhereted from CTroop class
038            //
039    
040            /////////////////////////////////////////////////////////////////////////////////////////////////////
041    
042            /**
043             * Request for medicine. 
044             * 
045             * This method sends a <b> FIPA REQUEST </b> message to all agents who offers the <tt> m_sMedicService </tt> service.
046             * 
047             * The content of message is: <tt> ( x , y , z ) ( health ) </tt>.
048             * 
049             * Variable <tt> m_iMedicsCount </tt> is updated.
050             * 
051             * <em> It's very useful to overload this method. </em>
052             * 
053             */
054    
055            protected void CallForMedic() {
056    
057                    try {
058    
059                            DFAgentDescription dfd = new DFAgentDescription();
060                            ServiceDescription sd = new ServiceDescription();
061                            sd.setType(m_sMedicService);
062                            dfd.addServices(sd);
063                            DFAgentDescription[] result = DFService.search(this, dfd);
064    
065                            if ( result.length > 0 ) {
066    
067                                    m_iMedicsCount = result.length;
068    
069                                    // Fill the REQUEST message
070                                    ACLMessage msg = new ACLMessage(ACLMessage.REQUEST);
071    
072                                    for ( int i = 0; i < result.length; i++ ) {
073    
074                                            DFAgentDescription dfdMedic = result[i];
075                                            AID Medic = dfdMedic.getName();
076                                            if ( ! Medic.equals(getName()) )
077                                                    msg.addReceiver(dfdMedic.getName());
078                                            else
079                                                    m_iMedicsCount--;
080                                    }
081                                    msg.setProtocol(FIPANames.InteractionProtocol.FIPA_REQUEST);
082                                    msg.setConversationId("CFM");
083                                    msg.setContent(" ( " + m_Movement.getPosition().x + " , " + m_Movement.getPosition().y + " , " + m_Movement.getPosition().z + " ) ( " + GetHealth() + " ) ");
084                                    send(msg);
085                                    System.out.println(getLocalName()+ ": Need a Medic! (v21)");                    
086    
087                            } else {
088                                    m_iMedicsCount = 0;
089                            }
090                    } catch (FIPAException fe) {
091                            fe.printStackTrace();
092                    }
093            }
094            /////////////////////////////////////////////////////////////////////////////////////////////////////
095    
096            /////////////////////////////////////////////////////////////////////////////////////////////////////
097            /**
098             * Request for ammunition. 
099             * 
100             * This method sends a <b> FIPA REQUEST </b> message to all agents who offers the <tt> m_sAmmoService </tt> service.
101             * 
102             * The content of message is: <tt> ( x , y , z ) ( ammo ) </tt>.
103             * 
104             * Variable <tt> m_iFieldOpsCount </tt> is updated.
105             * 
106             * <em> It's very useful to overload this method. </em>
107             *    
108             */
109            protected void CallForAmmo() {
110                    
111                    super.CallForAmmo();
112    
113            }
114            /////////////////////////////////////////////////////////////////////////////////////////////////////
115    
116            
117            /////////////////////////////////////////////////////////////////////////////////////////////////////
118            /**
119             * Request for backup. 
120             * 
121             * This method sends a <b> FIPA REQUEST </b> message to all agents who offers the <tt> m_sBackupService</tt> service.
122             * 
123             * The content of message is: <tt> ( x , y , z ) ( SoldiersCount ) </tt>.
124             * 
125             * Variable <tt> m_iSoldiersCount </tt> is updated.
126             * 
127             * <em> It's very useful to overload this method. </em>
128             *    
129             */
130            protected void CallForBackup() {
131                    
132    
133                    super.CallForBackup();
134    
135            }
136            /////////////////////////////////////////////////////////////////////////////////////////////////////
137    
138    
139    
140            /////////////////////////////////////////////////////////////////////////////////////////////////////
141            /**
142             * Update priority of all 'prepared (to execute)' tasks. 
143             * 
144             * This method is invoked in the state <em>STANDING</em>, and it's used to re-calculate the priority of all tasks (targets) int the task list
145             * of the agent. The reason is because JGOMAS Kernel always execute the maximum priority task. 
146             * 
147             * <em> It's very useful to overload this method. </em>
148             *    
149             */
150            protected void UpdateTargets() {} 
151            /////////////////////////////////////////////////////////////////////////////////////////////////////
152    
153            /////////////////////////////////////////////////////////////////////////////////////////////////////
154            /**
155             * Should we update now all 'prepared (to execute)' tasks? 
156             * 
157             * This method is a decision function invoked in the state <em>GOTO_TARGET</em>. A value of <tt> TRUE</tt> break out the inner loop, 
158             * making possible to JGOMAS Kernel extract a more priority task, or update some attributes of the current task.
159             * By default, the return value is <tt> FALSE</tt>, so we execute the current task until it finalizes.
160             *   
161             * <em> It's very useful to overload this method. </em>
162             *   
163             * @return <tt> FALSE</tt> 
164             * 
165             */
166            protected boolean ShouldUpdateTargets() { return false; }  
167            /////////////////////////////////////////////////////////////////////////////////////////////////////
168    
169            /////////////////////////////////////////////////////////////////////////////////////////////////////
170            /**
171             * The agent has got the objective pack. 
172             * 
173             * This method is called when this agent walks on the objective pack, getting it.
174             *   
175             * <em> It's very useful to overload this method. </em>
176             *   
177             */
178            protected void ObjectivePackTaken() {} // Should we do anything when we take the objective pack? 
179            /////////////////////////////////////////////////////////////////////////////////////////////////////
180    
181            /////////////////////////////////////////////////////////////////////////////////////////////////////
182            /**
183             * Definition of priorities for each kind of task. 
184             * 
185             * This method can be implemented in CTroop's derived classes to define the task's priorities in agreement to
186             * the role of the new class. Priorities must be defined in the array <tt> m_TaskPriority</tt>. 
187             *   
188             * <em> It's very useful to overload this method. </em>
189             *   
190             */
191            protected void SetUpPriorities() {
192                    
193                    m_TaskPriority[CTask.TASK_NONE] = 0;
194                    m_TaskPriority[CTask.TASK_GIVE_MEDICPAKS] = 2000;
195                    m_TaskPriority[CTask.TASK_GIVE_AMMOPACKS] = 0;
196                    m_TaskPriority[CTask.TASK_GIVE_BACKUP] = 0;
197                    m_TaskPriority[CTask.TASK_GET_OBJECTIVE] = 1000;
198                    m_TaskPriority[CTask.TASK_ATTACK] = 1000;
199                    m_TaskPriority[CTask.TASK_RUN_AWAY] = 1500;
200                    m_TaskPriority[CTask.TASK_GOTO_POSITION] = 750;
201                    m_TaskPriority[CTask.TASK_PATROLLING] = 500;
202                    m_TaskPriority[CTask.TASK_WALKING_PATH] = 750;
203    
204            }
205            /////////////////////////////////////////////////////////////////////////////////////////////////////
206    
207            /////////////////////////////////////////////////////////////////////////////////////////////////////
208            /**
209             * Action to do if this agent cannot shoot. 
210             * 
211             * This method is called when the agent try to shoot, but has no ammo. The agent will spit enemies out. :-) 
212             *   
213             * <em> It's very useful to overload this method. </em>
214             *   
215             */
216            protected void PerformNoAmmoAction() {}
217            /////////////////////////////////////////////////////////////////////////////////////////////////////
218    
219            /////////////////////////////////////////////////////////////////////////////////////////////////////
220            /**
221             * Calculates a new destiny position to escape. 
222             * 
223             * This method is called before the agent creates a task for escaping. It generates a valid random point in a radius of 50 units.
224             * Once position is calculated, agent updates its destiny to the new position, and automatically calculates the new direction.
225             *   
226             * <em> It's very useful to overload this method. </em>
227             *   
228             */
229            protected void GenerateEscapePosition() {
230            
231                    while (true) {
232                            m_Movement.CalculateNewDestination(50, 50);
233                            if ( CheckStaticPosition(m_Movement.getDestination().x, m_Movement.getDestination().z) == true ) {
234                                    m_Movement.CalculateNewOrientation();
235                                    return;
236                            }
237                    }
238            }
239            /////////////////////////////////////////////////////////////////////////////////////////////////////
240            
241            /////////////////////////////////////////////////////////////////////////////////////////////////////
242            /**
243             * Calculates a new destiny position to walk. 
244             * 
245             * This method is called before the agent creates a <tt> TASK_GOTO_POSITION</tt> task. It will try (for 5 attempts) to generate a
246             * valid random point in a radius of 20 units. If it doesn't generate a valid position in this cycle, it will try it in next cycle. 
247             * Once a position is calculated, agent updates its destination to the new position, and automatically calculates the new direction.
248             *   
249             * <em> It's very useful to overload this method. </em>
250             *   
251             * @return <tt> TRUE</tt>: valid position generated / <tt> FALSE</tt> cannot generate a valid position
252             * 
253             */
254            protected boolean GeneratePath() {
255                    
256                    for (int iAttempts = 0; iAttempts < 5; iAttempts++) {
257                            m_Movement.CalculateNewDestination(20,20);
258                            if ( CheckStaticPosition(m_Movement.getDestination().x, m_Movement.getDestination().z) == true ) {
259                                    // we must insert a task to go to a new position, so agent will follow previous path
260                                    String sNewPosition = " ( " + m_Movement.getDestination().x + " , " + m_Movement.getDestination().y + " , " + m_Movement.getDestination().z + " ) "; 
261                                    AddTask(CTask.TASK_GOTO_POSITION, getAID(), sNewPosition, m_CurrentTask.getPriority() + 1);
262                                    return true;
263                            }
264                    }
265                    
266                    return false;
267            }
268            /////////////////////////////////////////////////////////////////////////////////////////////////////
269    
270            /////////////////////////////////////////////////////////////////////////////////////////////////////
271            /**
272             * Calculates an array of positions for patrolling. 
273             * 
274             * When this method is called, it creates an array of <tt> n</tt> random positions. For medics and fieldops, the rank of <tt> n</tt> is 
275             * [1..1]. For soldiers, the rank of <tt> n</tt> is [5..10].
276             *   
277             * <em> It's very useful to overload this method. </em>
278             *   
279             */
280            protected void CreateControlPoints() {
281    
282                    int iMaxCP = 0;
283                    
284                    switch ( m_eClass ) {
285                    case CLASS_MEDIC:
286                    case CLASS_FIELDOPS:
287                            super.CreateControlPoints();
288                            break;
289                            
290                    case CLASS_SOLDIER:
291                            iMaxCP = (int) (Math.random() * 5) + 5;
292                            m_ControlPoints = new Vector3D [iMaxCP];
293                            for (int i = 0; i < iMaxCP; i++ ) {
294                                    Vector3D ControlPoints = new Vector3D();
295                                    while (true) {
296                            
297                                            double x = m_Map.GetTargetX() + (25 - (Math.random() * 50));
298                                            double z = m_Map.GetTargetZ() + (25 - (Math.random() * 50));
299    
300                                            if ( CheckStaticPosition(x, z) == true ) {
301                                                    ControlPoints.x = x;
302                                                    ControlPoints.z = z;
303                                                    m_ControlPoints[i] = ControlPoints;
304                                                    break;
305                                            }
306                                    }
307                            }
308                            break;
309                            
310                    case CLASS_ENGINEER:
311                    case CLASS_NONE:
312                    default:
313                            break;
314                    }
315            }
316            /////////////////////////////////////////////////////////////////////////////////////////////////////
317    
318            /////////////////////////////////////////////////////////////////////////////////////////////////////
319            /**
320             * Action to do when an agent is being shot. 
321             * 
322             * This method is called every time this agent receives a messager from agent Manager informing it is being shot.
323             *   
324             * <em> It's very useful to overload this method. </em>
325             *   
326             */
327            protected void PerformInjuryAction() {
328            }
329            /////////////////////////////////////////////////////////////////////////////////////////////////////
330            
331            /////////////////////////////////////////////////////////////////////////////////////////////////////
332            /**
333             * Action to do when ammo or health values exceed the threshold allowed. 
334             * 
335             * This method is called when current values of ammo and health exceed the threshold allowed. These values are checked 
336             * by <tt> Launch_MedicAmmo_RequestBehaviour</tt> behaviour, every ten seconds. Perhaps it is convenient to create a 
337             * <tt> TASK_RUN_AWAY</tt> task.  
338             *   
339             * <em> It's very useful to overload this method. </em>
340             *   
341             */
342            protected void PerformThresholdAction() {
343                    
344                    GenerateEscapePosition();
345                    String sNewPosition = " ( " + m_Movement.getDestination().x + " , " + m_Movement.getDestination().y + " , " + m_Movement.getDestination().z + " ) "; 
346                    AddTask(CTask.TASK_RUN_AWAY, getAID(), sNewPosition, m_CurrentTask.getPriority() + 1);
347                    
348            }
349            /////////////////////////////////////////////////////////////////////////////////////////////////////
350            
351            /////////////////////////////////////////////////////////////////////////////////////////////////////
352            /**
353             * Calculates if there is an enemy at sight. 
354             * 
355             * This method scans the list <tt> m_FOVObjects</tt> (objects in the Field Of View of the agent) looking for an enemy.
356             * If an enemy agent is found, a value of <tt> TRUE</tt> is returned and variable <tt> m_AimedAgent</tt> is updated.
357             * Note that there is no criterion (proximity, etc.) for the enemy found.
358             * Otherwise, the return value is <tt> FALSE</tt>.
359             *   
360             * <em> It's very useful to overload this method. </em>
361             *   
362             * @return <tt> TRUE</tt>: enemy found / <tt> FALSE</tt> enemy not found
363             * 
364             */
365            protected boolean GetAgentToAim() {
366                    
367                    if ( m_FOVObjects.isEmpty() ) {
368                            m_AimedAgent = null;
369                            return false;
370                    }
371                    
372                    Iterator it = m_FOVObjects.iterator();
373                    while ( it.hasNext() ) {                                                
374                            CSight s = (CSight) it.next();
375                            if ( s.getType() >= CPack.PACK_NONE ) {
376                                    continue;
377                            }
378            
379                            int eTeam = s.getTeam();
380                            
381                            if ( m_eTeam == eTeam )
382                                    continue;
383                            
384                            m_AimedAgent = s;
385                            return true; 
386                    }
387                    m_AimedAgent = null;
388                    return false;
389            }
390            /////////////////////////////////////////////////////////////////////////////////////////////////////
391            
392            /////////////////////////////////////////////////////////////////////////////////////////////////////
393            /**
394             * Action to do when the agent is looking at. 
395             * 
396             * This method is called just after Look method has ended. 
397             *   
398             * <em> It's very useful to overload this method. </em>
399             * 
400             */
401            protected void PerformLookAction() {
402            }
403            /////////////////////////////////////////////////////////////////////////////////////////////////////
404    
405            // End of Methods to overload inhereted from CTroop class
406            /////////////////////////////////////////////////////////////////////////////////////////////////////
407    
408    
409    
410            /////////////////////////////////////////////////////////////////////////////////////////////////////
411            // Methods to overload inhereted from CMedic class
412            //
413    
414            /////////////////////////////////////////////////////////////////////////////////////////////////////
415            /**
416             * Decides if agent accepts the CFM request 
417             * 
418             * This method is a decision function invoked when a CALL FOR MEDIC request has arrived.
419             * Parameter <tt> sContent</tt> is the content of message received in <tt> CFM</tt> responder behaviour as
420             * result of a <tt> CallForMedic</tt> request, so it must be: <tt> ( x , y , z ) ( health ) </tt>.
421             * By default, the return value is <tt> TRUE</tt>, so agents always accept all CFM requests.
422             *   
423             * <em> It's very useful to overload this method. </em>
424             *   
425             * @param _sContent
426             * @return <tt> TRUE</tt> 
427             * 
428             */
429            protected boolean checkMedicAction(String _sContent) {
430                    // We always go to help
431                    return ( true );
432            }
433            /////////////////////////////////////////////////////////////////////////////////////////////////////
434            
435    
436            /////////////////////////////////////////////////////////////////////////////////////////////////////
437            /**
438             * Action to do when this agent reaches the target of current task. 
439             * 
440             * This method is called when this agent goes to state <em>TARGET_REACHED</em>. If current task is <tt> TASK_GIVE_MEDICPAKS</tt>, 
441             * agent must give medic packs, but in other case, it calls to parent's method.
442             *   
443             * <em> It's very useful to overload this method. </em>
444             *   
445             * @param _CurrentTask
446             * 
447             */
448            protected void PerformTargetReached(CTask _CurrentTask) {
449                    
450                    switch ( _CurrentTask.getType() ) {
451                    case CTask.TASK_NONE:
452                            break;
453                            
454                    case CTask.TASK_GIVE_MEDICPAKS:
455                            int iPacks = _CurrentTask.getPacksDelivered();
456                            super.PerformTargetReached(_CurrentTask);
457                            if ( iPacks != _CurrentTask.getPacksDelivered() )
458                                    System.out.println(getLocalName()+ ": Medic has left " + (_CurrentTask.getPacksDelivered() - iPacks) + " Medic Packs");
459                            else
460                                    System.out.println(getLocalName()+ ": Medic cannot leave Medic Packs");
461                            break;
462                            
463                    default:
464                            super.PerformTargetReached(_CurrentTask);
465                            break;
466                    }
467            }
468            /////////////////////////////////////////////////////////////////////////////////////////////////////
469    
470            // End of Methods to overload inhereted from CMedic class
471            /////////////////////////////////////////////////////////////////////////////////////////////////////
472    
473    
474    }
475    
476    
477