6 |
*/ |
*/ |
7 |
|
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ************* RENDERMAN LINKS FREAK OUT ***************** |
|
|
|
|
|
|
|
|
#include <string> |
|
|
#include <time.h> |
|
|
#include <iostream> |
|
|
|
|
|
|
|
9 |
#include "pod.h" |
#include "pod.h" |
10 |
#include "../map/pathfinding/mapsearch_pod.h" |
|
|
#include "../map/pathfinding/stlastar.h" |
|
|
#include "../map/map.h" |
|
|
#include "msg_port.h" |
|
|
#include "../shapes/shape.h" |
|
|
#include "../visual/renderman.h" |
|
11 |
|
|
12 |
|
|
13 |
// constants |
// constants |
14 |
const long TIMING_LOOP_DELAY = 50000; // ticks per re-display for *UNIX only* in shell debug output |
static const long TIMING_LOOP_DELAY = 75000; // ticks per re-display for *UNIX only* in shell debug output |
15 |
const int MAX_POD_SIZE = 500; // the number the combined size of all shapes in the pod must not exceed. |
static const int MAX_POD_SIZE = 500; // the number the combined size of all shapes in the pod must not exceed. |
16 |
const int MAX_NUM_SHAPES = 12; // even if the MAX_POD_SIZE should allow it, number of shapes in the pod should not exceed this. |
static const int MAX_NUM_SHAPES = 12; // even if the MAX_POD_SIZE should allow it, number of shapes in the pod should not exceed this. |
17 |
const int ROAD_TRAMPLE_DIVISOR = 20; // road trample = pod size / trample divisor |
static const int ROAD_TRAMPLE_DIVISOR = 50; // FIXME: ~70 after football demo. road trample = pod size / trample divisor :: 50 is average for most shapes. |
18 |
|
|
19 |
|
|
20 |
|
|
21 |
// static variables: |
// static variables: |
|
//Map* Pod::map; // a pointer to the map. |
|
22 |
int Pod::id_counter = 0; // unique pod ID counter |
int Pod::id_counter = 0; // unique pod ID counter |
23 |
vector<Pod*> Pod::pod_index; // a vector of pointers to pods. now we can look them up by ID number |
vector<Pod*> Pod::pod_index; // a vector of pointers to pods. now we can look them up by ID number |
24 |
|
|
25 |
|
|
|
// declared elsewhere: |
|
|
//extern RenderMan* rm; |
|
|
|
|
26 |
|
|
27 |
// list of fun names: |
// list of fun names: |
28 |
// TODO: put these in a config file someday. someday.... |
// TODO: put these in a config file someday. someday.... |
62 |
def = 60; |
def = 60; |
63 |
opac = 40; |
opac = 40; |
64 |
acu = 65; |
acu = 65; |
65 |
size = 30; // aka "weight" |
size = 1; // aka "weight" |
66 |
spd = 70; |
spd = 70; |
67 |
xp = 0; |
xp = 0; |
68 |
|
|
72 |
avoid = 1; |
avoid = 1; |
73 |
engage = 1; |
engage = 1; |
74 |
|
|
75 |
msgport = new MsgPort(*this); |
msgport = new MsgPort(this); |
76 |
|
|
77 |
// idle is the default mission |
// idle is the default mission |
78 |
AddMission(IDLE, -1); |
AddMission(MISSION_IDLE, -1); |
79 |
|
|
80 |
// add to pod index |
// add to pod index |
81 |
AddPod(this); |
AddPod(this); |
111 |
moves.erase( moves.begin()+i ); |
moves.erase( moves.begin()+i ); |
112 |
} |
} |
113 |
|
|
114 |
// do not reduce id_counter - it just goes up to make new IDs. it's not a pod count. use pod_index.size() for that |
// destroy all shapes inside |
115 |
|
max = shapes.size(); |
116 |
|
for (int i = max-1; i >= 0; i--) { // go backwards so vector index numbers don't collapse |
117 |
|
delete shapes[i]; |
118 |
|
shapes.erase( shapes.begin()+i ); |
119 |
|
} |
120 |
|
|
121 |
// remove from pod vector |
// remove from pod vector |
122 |
max = pod_index.size(); |
max = pod_index.size(); |
127 |
// remove from map - unset occupation |
// remove from map - unset occupation |
128 |
themap->UnsetOccu(x_pos, y_pos); |
themap->UnsetOccu(x_pos, y_pos); |
129 |
|
|
130 |
// FIXME destroy all shapes inside (if any - there shouldn't really be any) |
|
131 |
} |
} |
132 |
|
|
133 |
|
|
137 |
|
|
138 |
// GENERAL POD FUNCTIONS |
// GENERAL POD FUNCTIONS |
139 |
// ================================== |
// ================================== |
|
// map pointer setter - used for all pods. |
|
|
//void Pod::SetMapPointer(Map &incoming_map){ map = &incoming_map; } |
|
|
|
|
140 |
// adds a pod to the pod index |
// adds a pod to the pod index |
141 |
void Pod::AddPod(Pod* pod){ pod_index.push_back(pod); } |
void Pod::AddPod(Pod* pod){ pod_index.push_back(pod); } |
142 |
|
|
143 |
// get a pod pointer based on it's ID number |
// get a pod pointer based on it's ID number |
144 |
Pod* Pod::GetPod(int id){ |
Pod* Pod::GetPodByID(int id){ |
145 |
int max = pod_index.size(); |
int max = pod_index.size(); |
146 |
for (int i = 0; i < max; i++) { |
for (int i = 0; i < max; i++) { |
147 |
if (pod_index[i]->id == id) { return pod_index[i]; } |
if (pod_index[i]->id == id) { return pod_index[i]; } |
149 |
return NULL; |
return NULL; |
150 |
} |
} |
151 |
|
|
152 |
|
// get a pod pointer based on it's vector index |
153 |
|
Pod* Pod::GetPodByIndex(int i){ |
154 |
|
if (i >= pod_index.size()) { return NULL; } |
155 |
|
return pod_index[i]; |
156 |
|
} |
157 |
|
|
158 |
int Pod::GetNumPods() { return pod_index.size(); } |
int Pod::GetNumPods() { return pod_index.size(); } |
159 |
// ================================== |
// ================================== |
160 |
|
|
182 |
int Pod::GetXp(){ return xp; } |
int Pod::GetXp(){ return xp; } |
183 |
|
|
184 |
Mission* Pod::Misn(int x){ |
Mission* Pod::Misn(int x){ |
185 |
if (x > int (misn.size()) || x < 0 ) {return NULL;} |
if (x >= int(misn.size()) || x < 0 ) {return NULL;} |
186 |
else { return misn[x]; } |
else { return misn[x]; } |
187 |
} |
} |
188 |
|
|
189 |
posn* Pod::Moves(int x){ |
posn* Pod::Moves(int x){ |
190 |
if (x > int (moves.size()) || x < 0 ) {return NULL;} |
if (x >= int(moves.size()) || x < 0 ) {return NULL;} |
191 |
else { return moves[x]; } |
else { return moves[x]; } |
192 |
} |
} |
193 |
// ================================== |
// ================================== |
244 |
if ( p > int(misn.size()) || p < 0 ) { return 0; } |
if ( p > int(misn.size()) || p < 0 ) { return 0; } |
245 |
|
|
246 |
// if we already have 3 missions, can't add any more: |
// if we already have 3 missions, can't add any more: |
247 |
if ( int(misn.size()) > 3 ) { return 0; } |
if ( int(misn.size()) >= 3 ) { return 0; } |
248 |
|
|
249 |
Mission* temp; |
Mission* temp; |
250 |
|
|
251 |
switch(m) { |
switch(m) { |
252 |
case PATROL: |
case MISSION_IDLE: |
253 |
temp = new Patrol(*this, x_pos, y_pos, 4, 0); |
temp = new MissionIdle(this); |
254 |
misn.insert( misn.begin()+p, temp); |
misn.insert( misn.begin()+p, temp); |
255 |
break; |
break; |
256 |
case IDLE: |
case MISSION_PATROL: |
257 |
temp = new Idle(*this); |
temp = new MissionPatrol(this, x_pos, y_pos, 4, 0); |
258 |
misn.insert( misn.begin()+p, temp); |
misn.insert( misn.begin()+p, temp); |
259 |
break; |
break; |
260 |
default: // IDLE |
case MISSION_MOVE: |
261 |
temp = new Idle(*this); |
temp = new MissionMove(this); |
262 |
|
misn.insert( misn.begin()+p, temp); |
263 |
|
break; |
264 |
|
case MISSION_HALT: |
265 |
|
temp = new MissionHalt(this); |
266 |
misn.insert( misn.begin()+p, temp); |
misn.insert( misn.begin()+p, temp); |
267 |
|
break; |
268 |
|
default: // IDLE |
269 |
|
//temp = new MissionIdle(this); |
270 |
|
//misn.insert( misn.begin()+p, temp); |
271 |
|
std::cout<< "POD NOT PROGRAMMED TO ADD MISSION \"" << Mission::TranslateMission(m) <<"\"" << endl << flush; |
272 |
// fall |
// fall |
273 |
} |
} |
274 |
|
|
275 |
|
// if the last mission in the list in IDLE, get rid of it. |
276 |
|
if (misn[ misn.size()-1 ]->GetType() == MISSION_IDLE && misn.size()-1 != 0) { RemoveMission( misn.size()-1 ); } |
277 |
|
|
278 |
return 1; |
return 1; |
279 |
} |
} |
280 |
|
|
288 |
|
|
289 |
delete misn[p]; |
delete misn[p]; |
290 |
misn.erase( misn.begin()+p ); |
misn.erase( misn.begin()+p ); |
291 |
|
|
292 |
|
// error: check to see if there are any more missions left. if not, assign IDLE as default. pods cannot have zero missions total |
293 |
|
if (misn.size() == 0) { AddMission(MISSION_IDLE); } |
294 |
|
|
295 |
return 1; |
return 1; |
296 |
} |
} |
297 |
|
|
298 |
|
int Pod::GetNumMissions() { return misn.size();} |
299 |
// ================================== |
// ================================== |
300 |
|
|
301 |
|
|
317 |
} |
} |
318 |
|
|
319 |
|
|
320 |
bool Pod::AddShape(Shape &s) { |
bool Pod::AddShape(Shape* s) { |
321 |
// return 0 if can't add, 1 if success |
// return 0 if can't add, 1 if success |
322 |
|
|
323 |
// if we already have 12 shapes |
// if we already have 12 shapes |
324 |
if ( int(shapes.size()) >= MAX_NUM_SHAPES ) { return 0; } |
if ( int(shapes.size()) >= MAX_NUM_SHAPES ) { return 0; } |
325 |
|
|
326 |
// if pod size is exceeded |
// if pod size is exceeded |
327 |
if ( ( size + s.GetSize() ) > MAX_POD_SIZE) { return 0; } |
if ( ( size + s->GetSize() ) >= MAX_POD_SIZE) { return 0; } |
328 |
|
|
329 |
// make the pod bigger: |
// make the pod bigger: |
330 |
size += s.GetSize(); |
size += s->GetSize(); |
331 |
|
|
332 |
// TODO: change pod stats and bonuses |
// TODO: change pod stats and bonuses |
333 |
|
|
334 |
shapes.insert( shapes.end(), &s); |
shapes.insert( shapes.end(), s); |
335 |
return 1; |
return 1; |
336 |
} |
} |
337 |
|
|
370 |
|
|
371 |
return 0; // not found |
return 0; // not found |
372 |
} |
} |
373 |
|
|
374 |
|
int Pod::GetNumShapes() { return shapes.size(); } |
375 |
// ================================== |
// ================================== |
376 |
|
|
377 |
|
|
393 |
if ( p > int(moves.size()) || p < 0 ) { return 0; } |
if ( p > int(moves.size()) || p < 0 ) { return 0; } |
394 |
|
|
395 |
// if we already have 3 moves, can't add any more: |
// if we already have 3 moves, can't add any more: |
396 |
if ( int(moves.size()) > 3 ) { return 0; } |
if ( int(moves.size()) >= 3 ) { return 0; } |
397 |
|
|
398 |
posn* temp = new posn(x,y); |
posn* temp = new posn(x,y); |
399 |
moves.insert( moves.begin()+p, temp); |
moves.insert( moves.begin()+p, temp); |
500 |
|
|
501 |
|
|
502 |
|
|
503 |
bool Pod::Walk() { |
int Pod::Walk() { |
504 |
// moves the pod across the map along the specified path until it runs out of juice. |
// moves the pod across the map along the specified path until it runs out of juice. |
505 |
// return zero if goal was not hit, 1 if success |
// return zero if goal was not hit, 1 if success, -1 if killed en route |
506 |
|
|
507 |
// FIXME ERROR: got path? |
// FIXME ERROR: got path? |
508 |
|
|
552 |
|
|
553 |
|
|
554 |
// trample road |
// trample road |
555 |
themap->TrampleRoad(is->x, is->y, (size / ROAD_TRAMPLE_DIVISOR) ); // TODO: adjust trample weight (?) |
themap->TrampleRoad(is->x, is->y, int((size / ROAD_TRAMPLE_DIVISOR) + 0.5) ); // TODO: adjust trample weight (?) |
556 |
|
|
557 |
// TODO: pick up map specials |
// TODO: pick up map specials |
558 |
|
|
559 |
// timing loop and shell display |
// timing loop and shell display |
560 |
clock_t s = clock(); |
clock_t s = clock(); |
561 |
while ( (clock() - s) < TIMING_LOOP_DELAY) {continue;} // NOTE: unix dependent time ticks |
while ( (clock() - s) < TIMING_LOOP_DELAY) {continue;} // NOTE: unix dependent time ticks |
562 |
//system("clear"); |
// move the pod on the screen |
563 |
//map->PrintToScreen(); |
rm->MovePod(was->x, was->y, is->x, is->y); |
|
|
|
|
rm->MovePod(was->x, was->y, is->x, is->y); |
|
564 |
|
|
565 |
// Engagement Prompt (will you marry me? :-) |
// Engagement Prompt (will you marry me? :-) |
566 |
// check for enemy occupations in each adjascent tile |
// check for enemy occupations in each adjascent tile |
572 |
enemy = themap->GetOccu(is->x + x_coords[i], is->y + y_coords[i]); |
enemy = themap->GetOccu(is->x + x_coords[i], is->y + y_coords[i]); |
573 |
if (enemy != NULL) { // if it's occupied |
if (enemy != NULL) { // if it's occupied |
574 |
if (enemy->GetAlign() != this->GetAlign()) { // if he's a bad guy |
if (enemy->GetAlign() != this->GetAlign()) { // if he's a bad guy |
575 |
PromptEngagement(enemy); // let's fight! (or not) |
// IF I DIE, DON'T KEEP GOING! segfaults happen, man! |
576 |
|
if (rm->StartCombat(this, enemy) == 0) { return -1; } // got killed |
577 |
|
// if won or not fought, go on |
578 |
} |
} |
579 |
} |
} |
580 |
} |
} |
601 |
|
|
602 |
// MISC FUNCTIONS |
// MISC FUNCTIONS |
603 |
// ================================== |
// ================================== |
604 |
void Pod::PromptEngagement(Pod* enemy) { |
int Pod::PromptEngagement(Pod* enemy) { |
605 |
/* TODO: function not made yet */ |
// 1 if we attacked and won, |
606 |
//cout << "Found Adjascent Enemy Pod! Shall i tear his arms off, sir?\n"; |
// 0 if no attack |
607 |
|
// -1 if killed by other pod |
608 |
// decide to fight depending on what engagement set to. |
|
609 |
if (0) { /*fight*/ } |
// try to find a way to do this without recursive function calls; |
610 |
|
|
611 |
// otherwise, send signal to the other pod so he can fight us if he wants |
return ( rm->StartCombat(this, enemy) == 1 ) ? 1 : -1; |
612 |
|
//if (won == 1) { return 1; } // if they won, we lossed |
613 |
|
//else { return -1; } |
614 |
|
//return 0; |
615 |
|
|
616 |
|
/* |
617 |
|
// my engagement |
618 |
|
int e = this->GetEngage(); |
619 |
|
|
620 |
|
// if i'm supposed to fight anybody: |
621 |
|
if (e == 0) { |
622 |
|
return rm->StartCombat(this, enemy); |
623 |
|
} |
624 |
|
else if (e == 1) { // fight if he is bigger than me |
625 |
|
if (enemy->GetNumShapes() >= this->GetNumShapes()) { |
626 |
|
return rm->StartCombat(this, enemy); |
627 |
|
} |
628 |
|
} |
629 |
|
else if (e == 2) { // fight if he is smaller than me |
630 |
|
if (enemy->GetNumShapes() <= this->GetNumShapes()) { |
631 |
|
return rm->StartCombat(this, enemy); |
632 |
|
} |
633 |
|
} |
634 |
|
// otherwise we opt out: send signal to the other pod so he can fight us if he wants |
635 |
|
// else { msgport->Send(enemy, MSG_ATTACK); } |
636 |
else { |
else { |
637 |
msgport->Send(enemy, MSG_ATTACK); |
int won = enemy->PromptEngagement(this); |
638 |
|
if (won == 1) { return -1; } // if they won, we lossed |
639 |
|
else if (won == 0) { return 0; } |
640 |
|
else if (won == -1) { return 1; } |
641 |
} |
} |
642 |
|
*/ |
643 |
|
|
644 |
} |
} |
645 |
|
|