qtgui: parent the agent injector/brain viewer correctly, and fix some onSelect functi...
[openc2e.git] / CompoundAgent.cpp
blobc52a73998fa138a7f8bb38ba8586365ba367890f
1 /*
2 * CompoundAgent.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 "CompoundAgent.h"
21 #include "openc2e.h"
22 #include "World.h"
23 #include "Engine.h" // version
24 #include <algorithm> // sort
25 #include <functional> // binary_function
26 #include "caosVM.h" // calculateScriptId
28 // the list of parts is a list of pointers to CompoundPart, so we need a custom sort
29 struct less_part : public std::binary_function<CompoundPart *, CompoundPart *, bool> {
30 bool operator()(CompoundPart *x, CompoundPart *y) { return *x < *y; }
33 void CompoundAgent::addPart(CompoundPart *p) {
34 assert(p);
35 assert(!part(p->id)); // todo: handle better
37 // todo: we should prbly insert at the right place, not call sort
38 parts.push_back(p);
39 std::sort(parts.begin(), parts.end(), less_part());
42 void CompoundAgent::delPart(unsigned int id) {
43 caos_assert(id != 0);
45 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) {
46 if ((*x)->id == id) { delete *x; parts.erase(x); return; }
49 throw caosException("delPart got a bad id"); // TODO: handle this exception properly
52 CompoundPart *CompoundAgent::part(unsigned int id) {
53 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) {
54 if ((*x)->id == id) return *x;
56 return 0;
59 CompoundAgent::CompoundAgent(unsigned char _family, unsigned char _genus, unsigned short _species, unsigned int plane,
60 std::string spritefile, unsigned int firstimage, unsigned int imagecount) :
61 Agent(_family, _genus, _species, plane) {
62 // TODO: we ignore image count acos it sucks
63 CompoundPart *p = new DullPart(this, 0, spritefile, firstimage, 0, 0, 0);
64 caos_assert(p);
65 addPart(p);
67 for (unsigned int i = 0; i < 6; i++) {
68 hotspots[i].left = -1; hotspots[i].right = -1; hotspots[i].top = -1;
69 hotspots[i].bottom = -1;
70 hotspotfunctions[i].hotspot = -1;
74 CompoundAgent::CompoundAgent(std::string _spritefile, unsigned int _firstimage, unsigned int _imagecount) : Agent(0, 0, 0, 0) {
75 // TODO: think about plane
77 spritefile = _spritefile;
78 firstimage = _firstimage;
79 imagecount = _imagecount;
81 for (unsigned int i = 0; i < 6; i++) {
82 hotspots[i].left = -1; hotspots[i].right = -1; hotspots[i].top = -1;
83 hotspots[i].bottom = -1;
84 hotspotfunctions[i].hotspot = -1;
88 CompoundAgent::~CompoundAgent() {
89 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) {
90 delete *x;
94 void CompoundAgent::setZOrder(unsigned int plane) {
95 Agent::setZOrder(plane);
96 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) (*x)->zapZOrder();
97 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) (*x)->addZOrder();
100 void CompoundAgent::tick() {
101 if (!paused) {
102 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) {
103 (*x)->tick();
107 Agent::tick();
110 void CompoundAgent::handleClick(float clickx, float clicky) {
111 if (engine.version > 2) {
112 Agent::handleClick(clickx, clicky);
113 return;
116 // the hotspots are relative to us
117 clickx -= x; clicky -= y;
119 // TODO: this whole thing needs more thought/work
121 unsigned int i = 0;
122 if (engine.version == 1) i = 3; // skip C1 creature-only points
123 for (; i < 6; i++) {
124 if (hotspotfunctions[i].hotspot < 0) continue;
125 if (hotspotfunctions[i].hotspot >= 6) continue;
126 unsigned short func;
127 if (engine.version == 1) {
128 // C1: we only check 3/4/5
129 func = calculateScriptId(i - 3);
130 } else {
131 if (hotspotfunctions[i].mask == 1) continue; // creature only
132 func = calculateScriptId(hotspotfunctions[i].message);
135 int j = hotspotfunctions[i].hotspot;
137 if (hotspots[j].left == -1) continue;
138 // TODO: check other items for being -1?
140 if ((clickx >= hotspots[j].left && clickx <= hotspots[j].right) &&
141 (clicky >= hotspots[j].top && clicky <= hotspots[j].bottom)) {
142 queueScript(func, (Agent *)world.hand());
143 return;
148 void CompoundAgent::setHotspotLoc(unsigned int id, int l, int t, int r, int b) {
149 assert(id < 6);
151 hotspots[id].left = l;
152 hotspots[id].top = t;
153 hotspots[id].right = r;
154 hotspots[id].bottom = b;
157 void CompoundAgent::setHotspotFunc(unsigned int id, unsigned int f) {
158 assert(id < 6);
160 hotspotfunctions[id].hotspot = f;
162 // TODO: this tries to make c2 work nicely, necessary?
163 hotspotfunctions[id].mask = 3;
164 if (id < 3)
165 hotspotfunctions[id].message = calculateScriptId(id);
166 else
167 hotspotfunctions[id].message = calculateScriptId(id - 3);
170 void CompoundAgent::setHotspotFuncDetails(unsigned int id, uint16 m, uint8 f) {
171 assert(id < 6);
173 hotspotfunctions[id].message = m;
174 hotspotfunctions[id].mask = f;
177 /* vim: set noet: */