qtgui: parent the agent injector/brain viewer correctly, and fix some onSelect functi...
[openc2e.git] / Room.cpp
blob56e3a90b06c60a12bf142c538f9874e9d5acb529
1 /*
2 * Room.cpp
3 * openc2e
5 * Created by Alyssa Milburn on Tue May 25 2004.
6 * Copyright (c) 2004 Alyssa Milburn. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
20 #include "Room.h"
21 #include "World.h"
22 #include "Backend.h"
24 Room::Room() {
25 for (unsigned int i = 0; i < CA_COUNT; i++)
26 ca[i] = catemp[i] = 0.0f;
29 Room::Room(unsigned int x_l, unsigned int x_r, unsigned int y_l_t, unsigned int y_r_t,
30 unsigned int y_l_b, unsigned int y_r_b) {
31 if (x_l > x_r) std::swap(x_l, x_r);
32 x_left = x_l;
33 x_right = x_r;
34 if (y_l_b < y_l_t) std::swap(y_l_b, y_l_t);
35 if (y_r_b < y_r_t) std::swap(y_r_b, y_r_t);
36 y_left_ceiling = y_l_t;
37 y_right_ceiling = y_r_t;
38 y_left_floor = y_l_b;
39 y_right_floor = y_r_b;
41 Point ul(x_l, y_l_t);
42 Point ur(x_r, y_r_t);
43 Point bl(x_l, y_l_b);
44 Point br(x_r, y_r_b);
46 left = Line(ul, bl);
47 right = Line(ur, br);
48 top = Line(ul, ur);
49 bot = Line(bl, br);
51 for (unsigned int i = 0; i < CA_COUNT; i++)
52 ca[i] = catemp[i] = 0.0f;
55 void Room::tick() {
56 if (!type.hasInt()) return; // badness
58 if (world.carates.find(type.getInt()) == world.carates.end()) return;
59 std::map<unsigned int, cainfo> &rates = world.carates[type.getInt()];
61 for (unsigned int i = 0; i < CA_COUNT; i++) {
62 if (rates.find(i) == rates.end()) continue;
63 cainfo &info = rates[i];
65 // adjust for loss
66 ca[i] -= (ca[i] * info.loss);
68 if (catemp[i] > 1.0f) catemp[i] = 1.0f;
69 else if (catemp[i] < 0.0f) catemp[i] = 0.0f;
71 // adjust for gain from agents
72 if (catemp[i] > ca[i]) {
73 float diff = catemp[i] - ca[i];
74 catemp[i] = ca[i] + (diff * info.gain);
75 if (catemp[i] > 1.0f)
76 catemp[i] = 1.0f;
77 } else {
78 catemp[i] = ca[i];
83 void Room::postTick() {
84 if (!type.hasInt()) return; // badness
86 if (world.carates.find(type.getInt()) == world.carates.end()) return;
87 std::map<unsigned int, cainfo> &rates = world.carates[type.getInt()];
89 for (unsigned int i = 0; i < CA_COUNT; i++) {
90 if (rates.find(i) == rates.end()) continue;
91 cainfo &info = rates[i];
93 ca[i] = catemp[i];
95 // adjust for diffusion to/from surrounding rooms
96 // TODO: absolutely no clue if this is correct
97 for (std::map<boost::weak_ptr<Room>,RoomDoor *>::iterator d = doors.begin(); d != doors.end(); d++) {
98 shared_ptr<Room> dest = (d->second->first.lock().get() == this) ? d->second->second.lock() : d->second->first.lock();
99 assert(dest);
100 float possiblediffusion = (dest->catemp[i] * info.diffusion * (d->second->perm / 100.0f));
101 if (possiblediffusion > 1.0f) possiblediffusion = 1.0f;
102 if (possiblediffusion > ca[i])
103 ca[i] = possiblediffusion;
108 void Room::resetTick() {
109 for (unsigned int i = 0; i < CA_COUNT; i++)
110 catemp[i] = 0.0f;
113 void Room::renderBorders(class Surface *surface, int adjustx, int adjusty, unsigned int col) {
114 // ceiling
115 surface->renderLine(x_left - adjustx, y_left_ceiling - adjusty,
116 x_right - adjustx, y_right_ceiling - adjusty,
117 col);
118 // floor
119 surface->renderLine(x_left - adjustx, y_left_floor - adjusty,
120 x_right - adjustx, y_right_floor - adjusty,
121 col);
122 // left side
123 surface->renderLine(x_left - adjustx, y_left_ceiling - adjusty,
124 x_left - adjustx, y_left_floor - adjusty,
125 col);
126 // right side
127 surface->renderLine(x_right - adjustx, y_right_ceiling - adjusty,
128 x_right - adjustx, y_right_floor - adjusty,
129 col);
131 // c2 floor points
132 for (unsigned int i = 1; i < floorpoints.size(); i++) {
133 surface->renderLine(x_left + floorpoints[i - 1].first - adjustx, y_left_floor - floorpoints[i - 1].second - adjusty,
134 x_left + floorpoints[i].first - adjustx, y_left_floor - floorpoints[i].second - adjusty,
135 col);
139 float Room::floorYatX(float x) {
140 if (floorpoints.size()) {
141 unsigned int roomheight = y_left_floor - y_left_ceiling;
143 for (unsigned int i = 1; i < floorpoints.size(); i++) {
144 if (floorpoints[i].first + x_left < x) continue;
145 if (floorpoints[i - 1].first + x_left > x) break;
147 Point roomtl(x_left, y_left_ceiling);
149 Line floor(Point(floorpoints[i - 1].first, roomheight - floorpoints[i - 1].second),
150 Point(floorpoints[i].first, roomheight - floorpoints[i].second));
152 return floor.pointAtX(x - roomtl.x).y + roomtl.y;
156 return bot.pointAtX(x).y;
159 /* vim: set noet: */