* move imageManager code into new imageManager.h/imageManager.cpp
[openc2e.git] / CompoundAgent.cpp
blob70a271010e0e771be35bde525b7804862f0a8658
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 "c16Image.h"
23 #include "World.h"
24 #include "Engine.h" // version
25 #include <algorithm> // sort
26 #include <functional> // binary_function
27 #include "caosVM.h" // calculateScriptId
29 // the list of parts is a list of pointers to CompoundPart, so we need a custom sort
30 struct less_part : public std::binary_function<CompoundPart *, CompoundPart *, bool> {
31 bool operator()(CompoundPart *x, CompoundPart *y) { return *x < *y; }
34 void CompoundAgent::addPart(CompoundPart *p) {
35 assert(p);
36 assert(!part(p->id)); // todo: handle better
38 // todo: we should prbly insert at the right place, not call sort
39 parts.push_back(p);
40 std::sort(parts.begin(), parts.end(), less_part());
43 void CompoundAgent::delPart(unsigned int id) {
44 caos_assert(id != 0);
46 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) {
47 if ((*x)->id == id) { delete *x; parts.erase(x); return; }
50 throw caosException("delPart got a bad id"); // TODO: handle this exception properly
53 CompoundPart *CompoundAgent::part(unsigned int id) {
54 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) {
55 if ((*x)->id == id) return *x;
57 return 0;
60 CompoundAgent::CompoundAgent(unsigned char _family, unsigned char _genus, unsigned short _species, unsigned int plane,
61 std::string spritefile, unsigned int firstimage, unsigned int imagecount) :
62 Agent(_family, _genus, _species, plane) {
63 // TODO: we ignore image count acos it sucks
64 CompoundPart *p = new DullPart(this, 0, spritefile, firstimage, 0, 0, 0);
65 caos_assert(p);
66 addPart(p);
68 for (unsigned int i = 0; i < 6; i++) {
69 hotspots[i].left = -1; hotspots[i].right = -1; hotspots[i].top = -1;
70 hotspots[i].bottom = -1;
71 hotspotfunctions[i].hotspot = -1;
75 CompoundAgent::CompoundAgent(std::string _spritefile, unsigned int _firstimage, unsigned int _imagecount) : Agent(0, 0, 0, 0) {
76 // TODO: think about plane
78 spritefile = _spritefile;
79 firstimage = _firstimage;
80 imagecount = _imagecount;
82 for (unsigned int i = 0; i < 6; i++) {
83 hotspots[i].left = -1; hotspots[i].right = -1; hotspots[i].top = -1;
84 hotspots[i].bottom = -1;
85 hotspotfunctions[i].hotspot = -1;
89 CompoundAgent::~CompoundAgent() {
90 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) {
91 delete *x;
95 void CompoundAgent::setZOrder(unsigned int plane) {
96 Agent::setZOrder(plane);
97 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) (*x)->zapZOrder();
98 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) (*x)->addZOrder();
101 void CompoundAgent::tick() {
102 if (!paused) {
103 for (std::vector<CompoundPart *>::iterator x = parts.begin(); x != parts.end(); x++) {
104 (*x)->tick();
108 Agent::tick();
111 void CompoundAgent::handleClick(float clickx, float clicky) {
112 if (engine.version > 2) {
113 Agent::handleClick(clickx, clicky);
114 return;
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 queueScript(func, (Agent *)world.hand());
144 return;
149 void CompoundAgent::setHotspotLoc(unsigned int id, int l, int t, int r, int b) {
150 assert(id < 6);
152 hotspots[id].left = l;
153 hotspots[id].top = t;
154 hotspots[id].right = r;
155 hotspots[id].bottom = b;
158 void CompoundAgent::setHotspotFunc(unsigned int id, unsigned int f) {
159 assert(id < 6);
161 hotspotfunctions[id].hotspot = f;
163 // TODO: this tries to make c2 work nicely, necessary?
164 hotspotfunctions[id].mask = 3;
165 if (id < 3)
166 hotspotfunctions[id].message = calculateScriptId(id);
167 else
168 hotspotfunctions[id].message = calculateScriptId(id - 3);
171 void CompoundAgent::setHotspotFuncDetails(unsigned int id, uint16 m, uint8 f) {
172 assert(id < 6);
174 hotspotfunctions[id].message = m;
175 hotspotfunctions[id].mask = f;
178 /* vim: set noet: */