ccdevnet / openc2e

openc2e

This URL has Read+Write access

openc2e / src / AgentHelpers.cpp
100644 123 lines (98 sloc) 4.21 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* AgentHelpers.cpp
* openc2e
*
* Created by Alyssa Milburn on Sun Jul 23 2006.
* Copyright (c) 2006 Alyssa Milburn. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*/
 
#include "World.h"
#include "MetaRoom.h"
#include "Room.h"
 
bool agentIsVisible(Agent *seeing, Agent *a, float ownerx, float ownery, MetaRoom *ownermeta, shared_ptr<Room> ownerroom) {
assert(ownermeta && ownerroom);
 
if (seeing == a) return false;
 
// verify we're in the same metaroom as owner, and in a room
float thisx = a->x + (a->getWidth() / 2.0f);
float thisy = a->y + (a->getHeight() / 2.0f);
MetaRoom *m = world.map.metaRoomAt(thisx, thisy);
if (m != ownermeta) return false;
shared_ptr<Room> r = world.map.roomAt(thisx, thisy);
if (!r) return false;
 
// compare squared distance with range
double deltax = thisx - ownerx; deltax *= deltax;
double deltay = thisy - ownery; deltay *= deltay;
if ((deltax + deltay) > (seeing->range.getFloat() * seeing->range.getFloat())) return false;
 
// do the actual visibiltiy check using a line between centers
Point src(ownerx, ownery), dest(thisx, thisy);
Line dummywall; unsigned int dummydir;
shared_ptr<Room> newroom = ownerroom;
world.map.collideLineWithRoomSystem(src, dest, newroom, src, dummywall, dummydir, seeing->perm);
if (src != dest) return false;
 
return true;
}
 
bool agentIsVisible(Agent *seeing, Agent *dest) {
float ownerx = (seeing->x + (seeing->getWidth() / 2.0f));
float ownery = (seeing->y + (seeing->getHeight() / 2.0f));
MetaRoom *ownermeta = world.map.metaRoomAt(ownerx, ownery);
shared_ptr<Room> ownerroom = world.map.roomAt(ownerx, ownery);
if (!ownermeta) return false; if (!ownerroom) return false;
 
return agentIsVisible(seeing, dest, ownerx, ownery, ownermeta, ownerroom);
}
 
std::vector<boost::shared_ptr<Agent> > getVisibleList(Agent *seeing, unsigned char family, unsigned char genus, unsigned short species) {
std::vector<boost::shared_ptr<Agent> > agents;
 
float ownerx = (seeing->x + (seeing->getWidth() / 2.0f));
float ownery = (seeing->y + (seeing->getHeight() / 2.0f));
MetaRoom *ownermeta = world.map.metaRoomAt(ownerx, ownery);
shared_ptr<Room> ownerroom = world.map.roomAt(ownerx, ownery);
if (!ownermeta) return agents; if (!ownerroom) return agents;
 
for (std::list<boost::shared_ptr<Agent> >::iterator i
= world.agents.begin(); i != world.agents.end(); i++) {
boost::shared_ptr<Agent> a = (*i);
if (!a) continue;
 
// TODO: if owner is a creature, skip stuff with invisible attribute
 
// verify species/genus/family
if (species && species != a->species) continue;
if (genus && genus != a->genus) continue;
if (family && family != a->family) continue;
 
if (agentIsVisible(seeing, a.get(), ownerx, ownery, ownermeta, ownerroom))
agents.push_back(a);
}
 
return agents;
}
 
bool agentsTouching(Agent *first, Agent *second) {
assert(first && second);
 
// TODO: c2e docs say it only checks if bounding lines overlap, implement it like that?
 
// this check should probably be integrated into line overlap check?
if (first == second) return false;
 
if (first->x < second->x) {
if ((first->x + first->getWidth()) < second->x)
return false;
} else {
if ((second->x + second->getWidth()) < first->x)
return false;
}
 
if (first->y < second->y) {
if ((first->y + first->getHeight()) < second->y)
return false;
} else {
if ((second->y + second->getHeight()) < first->y)
return false;
}
 
return true;
}
 
shared_ptr<Room> roomContainingAgent(AgentRef agent) {
MetaRoom *m = world.map.metaRoomAt(agent->x, agent->y);
if (!m) return shared_ptr<Room>();
return m->roomAt(agent->x + (agent->getWidth() / 2.0f), agent->y + (agent->getHeight() / 2.0f));
}