read Blackboard data correctly from the SFC file, and construct a BlackboardPart...
[openc2e.git] / CompoundAgent.cpp
blob78305c09ee5bdcd9cee3317273ffecd04d91b6ae
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 int CompoundAgent::handleClick(float clickx, float clicky) {
111 if (!activateable()) return -1;
113 if (engine.version > 2) {
114 return Agent::handleClick(clickx, clicky);
117 // the hotspots are relative to us
118 clickx -= x; clicky -= y;
120 // TODO: this whole thing needs more thought/work
122 unsigned int i = 0;
123 if (engine.version == 1) i = 3; // skip C1 creature-only points
124 for (; i < 6; i++) {
125 if (hotspotfunctions[i].hotspot < 0) continue;
126 if (hotspotfunctions[i].hotspot >= 6) continue;
127 unsigned short func;
128 if (engine.version == 1) {
129 // C1: we only check 3/4/5
130 func = calculateScriptId(i - 3);
131 } else {
132 if (hotspotfunctions[i].mask == 1) continue; // creature only
133 func = calculateScriptId(hotspotfunctions[i].message);
136 int j = hotspotfunctions[i].hotspot;
138 if (hotspots[j].left == -1) continue;
139 // TODO: check other items for being -1?
141 if ((clickx >= hotspots[j].left && clickx <= hotspots[j].right) &&
142 (clicky >= hotspots[j].top && clicky <= hotspots[j].bottom)) {
143 return func;
147 return -1;
150 void CompoundAgent::setHotspotLoc(unsigned int id, int l, int t, int r, int b) {
151 assert(id < 6);
153 hotspots[id].left = l;
154 hotspots[id].top = t;
155 hotspots[id].right = r;
156 hotspots[id].bottom = b;
159 void CompoundAgent::setHotspotFunc(unsigned int id, unsigned int f) {
160 assert(id < 6);
162 hotspotfunctions[id].hotspot = f;
164 // TODO: this tries to make c2 work nicely, necessary?
165 hotspotfunctions[id].mask = 3;
166 if (id < 3)
167 hotspotfunctions[id].message = calculateScriptId(id);
168 else
169 hotspotfunctions[id].message = calculateScriptId(id - 3);
172 void CompoundAgent::setHotspotFuncDetails(unsigned int id, uint16 m, uint8 f) {
173 assert(id < 6);
175 hotspotfunctions[id].message = m;
176 hotspotfunctions[id].mask = f;
179 /* vim: set noet: */