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());
42 void CompoundAgent::delPart(unsigned int id
) {
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
;
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);
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
++) {
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() {
102 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
110 void CompoundAgent::handleClick(float clickx
, float clicky
) {
111 if (engine
.version
> 2) {
112 Agent::handleClick(clickx
, clicky
);
116 // the hotspots are relative to us
117 clickx
-= x
; clicky
-= y
;
119 // TODO: this whole thing needs more thought/work
122 if (engine
.version
== 1) i
= 3; // skip C1 creature-only points
124 if (hotspotfunctions
[i
].hotspot
< 0) continue;
125 if (hotspotfunctions
[i
].hotspot
>= 6) continue;
127 if (engine
.version
== 1) {
128 // C1: we only check 3/4/5
129 func
= calculateScriptId(i
- 3);
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());
148 void CompoundAgent::setHotspotLoc(unsigned int id
, int l
, int t
, int r
, int b
) {
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
) {
160 hotspotfunctions
[id
].hotspot
= f
;
162 // TODO: this tries to make c2 work nicely, necessary?
163 hotspotfunctions
[id
].mask
= 3;
165 hotspotfunctions
[id
].message
= calculateScriptId(id
);
167 hotspotfunctions
[id
].message
= calculateScriptId(id
- 3);
170 void CompoundAgent::setHotspotFuncDetails(unsigned int id
, uint16 m
, uint8 f
) {
173 hotspotfunctions
[id
].message
= m
;
174 hotspotfunctions
[id
].mask
= f
;