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"
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
) {
35 assert(!part(p
->id
)); // todo: handle better
37 // TODO: we should prbly insert at the right place, not call sort
39 std::sort(parts
.begin(), parts
.end(), less_part());
41 if (engine
.version
< 3 && parts
.size() == 1) { // adding the first part in c1/c2
42 // TODO: this is zorder hackery - probably the right thing to do, but needs thinking about more
43 unsigned int z
= p
->zorder
;
49 void CompoundAgent::delPart(unsigned int id
) {
52 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
53 if ((*x
)->id
== id
) { delete *x
; parts
.erase(x
); return; }
56 throw caosException("delPart got a bad id"); // TODO: handle this exception properly
59 CompoundPart
*CompoundAgent::part(unsigned int id
) {
60 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
61 if ((*x
)->id
== id
) return *x
;
66 CompoundAgent::CompoundAgent(unsigned char _family
, unsigned char _genus
, unsigned short _species
, unsigned int plane
,
67 std::string spritefile
, unsigned int firstimage
, unsigned int imagecount
) :
68 Agent(_family
, _genus
, _species
, plane
) {
69 // TODO: we ignore image count acos it sucks
70 CompoundPart
*p
= new DullPart(this, 0, spritefile
, firstimage
, 0, 0, 0);
74 setZOrder(plane
); // because addPart zots zorder for c1/c2, TODO: make saner?
76 for (unsigned int i
= 0; i
< 6; i
++) {
77 hotspots
[i
].left
= -1; hotspots
[i
].right
= -1; hotspots
[i
].top
= -1;
78 hotspots
[i
].bottom
= -1;
79 hotspotfunctions
[i
].hotspot
= -1;
83 CompoundAgent::CompoundAgent(std::string _spritefile
, unsigned int _firstimage
, unsigned int _imagecount
) : Agent(0, 0, 0, 0) {
84 // TODO: think about plane
86 spritefile
= _spritefile
;
87 firstimage
= _firstimage
;
88 imagecount
= _imagecount
;
90 for (unsigned int i
= 0; i
< 6; i
++) {
91 hotspots
[i
].left
= -1; hotspots
[i
].right
= -1; hotspots
[i
].top
= -1;
92 hotspots
[i
].bottom
= -1;
93 hotspotfunctions
[i
].hotspot
= -1;
97 CompoundAgent::~CompoundAgent() {
98 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
103 void CompoundAgent::setZOrder(unsigned int plane
) {
104 Agent::setZOrder(plane
);
105 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) (*x
)->zapZOrder();
106 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) (*x
)->addZOrder();
109 void CompoundAgent::tick() {
111 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
119 int CompoundAgent::handleClick(float clickx
, float clicky
) {
120 if (!activateable()) return -1;
122 if (engine
.version
> 2) {
123 return Agent::handleClick(clickx
, clicky
);
126 // the hotspots are relative to us
127 clickx
-= x
; clicky
-= y
;
129 // TODO: this whole thing needs more thought/work
132 if (engine
.version
== 1) i
= 3; // skip C1 creature-only points
134 if (hotspotfunctions
[i
].hotspot
< 0) continue;
135 if (hotspotfunctions
[i
].hotspot
>= 6) continue;
137 if (engine
.version
== 1) {
138 // C1: we only check 3/4/5
139 func
= calculateScriptId(i
- 3);
141 if (hotspotfunctions
[i
].mask
== 1) continue; // creature only
142 func
= calculateScriptId(hotspotfunctions
[i
].message
);
145 int j
= hotspotfunctions
[i
].hotspot
;
147 if (hotspots
[j
].left
== -1) continue;
148 // TODO: check other items for being -1?
150 if ((clickx
>= hotspots
[j
].left
&& clickx
<= hotspots
[j
].right
) &&
151 (clicky
>= hotspots
[j
].top
&& clicky
<= hotspots
[j
].bottom
)) {
159 bool CompoundAgent::fireScript(unsigned short event
, Agent
*from
, caosVar one
, caosVar two
) {
160 // TODO: this is a hack to deal with ACTV on compound agents in c1/c2
161 if (engine
.version
< 3 && actv
.getInt() == event
) return false;
163 return Agent::fireScript(event
, from
, one
, two
);
166 void CompoundAgent::setHotspotLoc(unsigned int id
, int l
, int t
, int r
, int b
) {
169 hotspots
[id
].left
= l
;
170 hotspots
[id
].top
= t
;
171 hotspots
[id
].right
= r
;
172 hotspots
[id
].bottom
= b
;
175 void CompoundAgent::setHotspotFunc(unsigned int id
, unsigned int f
) {
178 hotspotfunctions
[id
].hotspot
= f
;
180 // TODO: this tries to make c2 work nicely, necessary?
181 hotspotfunctions
[id
].mask
= 3;
183 hotspotfunctions
[id
].message
= calculateScriptId(id
);
185 hotspotfunctions
[id
].message
= calculateScriptId(id
- 3);
188 void CompoundAgent::setHotspotFuncDetails(unsigned int id
, uint16 m
, uint8 f
) {
191 hotspotfunctions
[id
].message
= m
;
192 hotspotfunctions
[id
].mask
= f
;