| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322 |
- #include "QuestGraph.h"
- #include <HashMap.h>
- #include <Image.h>
- #include <Scroll.h>
- #include <XML.h>
- #include "Globals.h"
- #include "Load.h"
- #include "World.h"
- QuestGraphElement::QuestGraphElement() {}
- bool QuestGraphElement::isApplicableFor(Framework::XML::Element& element)
- {
- return element.getName().isEqual("questGraph");
- }
- Framework::Drawable* QuestGraphElement::parseElement(
- Framework::XML::Element& element, Framework::UIMLContainer& generalFactory)
- {
- QuestGraph* graph = new QuestGraph();
- graph->collectionName = element.getAttributeValue("collectionName");
- graph->id = element.getAttributeValue("id");
- auto children = element.selectChildsByName("questGraphItem");
- Framework::HashMap<Framework::Text, QuestGraphItem*> map(
- 100, [](Framework::Text str) { return str.hashCode(); });
- // parse graph elements
- for (Framework::XML::Element* itemElement : children)
- {
- Framework::Drawable* parsed
- = generalFactory.parseElement(*itemElement, generalFactory);
- QuestGraphItem* item = dynamic_cast<QuestGraphItem*>(parsed);
- if (!item)
- {
- if (parsed)
- {
- parsed->release();
- }
- }
- else
- {
- map.put(item->getId(), item);
- }
- generalFactory.layout(*itemElement,
- *parsed,
- graph->getWidth(),
- graph->getHeight(),
- generalFactory);
- }
- // set connection references
- int connectionId = -1;
- for (MapEntry<Framework::Text, QuestGraphItem*> entry : map)
- {
- QuestGraphItem* item = entry.getValue();
- Framework::Text requirements = item->getRequirements();
- while (requirements.getLength() > 0)
- {
- connectionId++;
- Framework::Text* part = 0;
- if (requirements.has("||"))
- {
- part = requirements.getTeilText(
- 0, requirements.positionOf("||"));
- requirements.remove(0, requirements.positionOf("||") + 2);
- }
- else
- {
- part = new Framework::Text(requirements);
- requirements = "";
- }
- while (part->getLength() > 0)
- {
- Framework::Text* requirement;
- if (part->has("&&"))
- {
- requirement = part->getTeilText(0, part->positionOf("&&"));
- part->remove(0, part->positionOf("&&") + 2);
- }
- else
- {
- requirement = new Text(part->getText());
- part->setText("");
- }
- requirement->removeWhitespaceAfter(0);
- requirement->removeWhitespaceBefore(requirement->getLength());
- QuestGraphItem* requiredItem = map.get(*requirement);
- if (requiredItem)
- {
- requiredItem->addNextLayerRef({item, connectionId});
- item->addPreviousLayerRef({requiredItem, connectionId});
- }
- requirement->release();
- }
- part->release();
- }
- }
- // calculate layer index based on connections
- bool changed = 1;
- while (changed)
- {
- changed = 0;
- for (MapEntry<Framework::Text, QuestGraphItem*> entry : map)
- {
- changed |= entry.getValue()->calculateLaxerIndex();
- }
- }
- // add items to graph
- for (MapEntry<Framework::Text, QuestGraphItem*> entry : map)
- {
- if (entry.getValue()->getLayerIndex() < 0)
- {
- entry.getValue()->setVirtual(
- 1); // hide nodes witch layers could not be calculated because
- // of invalid circular connections
- }
- graph->addItem(entry.getValue());
- }
- graph->addVirtualConnectionNodes();
- graph->sortItems();
- graph->fixItemPositions();
- return graph;
- }
- bool QuestGraphElement::updateElement(Framework::XML::Element& element,
- Framework::Drawable& z,
- Framework::UIMLContainer& generalFactory)
- {
- return false;
- }
- void QuestGraphElement::layout(Framework::XML::Element& element,
- Framework::Drawable& z,
- int pWidth,
- int pHeight,
- Framework::UIMLContainer& generalLayouter)
- {
- UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter);
- QuestGraph* graph = dynamic_cast<QuestGraph*>(&z);
- graph->centerVertically();
- }
- QuestGraphItemElement::QuestGraphItemElement() {}
- bool QuestGraphItemElement::isApplicableFor(Framework::XML::Element& element)
- {
- return element.getName().isEqual("questGraphItem");
- }
- Framework::Drawable* QuestGraphItemElement::parseElement(
- Framework::XML::Element& element, Framework::UIMLContainer& generalFactory)
- {
- QuestGraphItem* item = new QuestGraphItem();
- Framework::Text name = element.getAttributeValue("name");
- Framework::Text description = element.getAttributeValue("description");
- item->setToolTipText(name + "\n" + description,
- generalFactory.getFactory().initParam.bildschirm,
- generalFactory.getFactory().initParam.font);
- item->setBackgroundImageZ(loadImage(element.getAttributeValue("image")));
- item->finished = (int)element.getAttributeValue("finished") != 0;
- if (item->finished)
- {
- item->setBorderColor(0xFF55FF00);
- }
- item->rewarded = (int)element.getAttributeValue("rewarded") != 0;
- item->mainQuest = (int)element.getAttributeValue("mainQuest") != 0;
- if (item->mainQuest)
- {
- item->setBorderWidth(3);
- }
- item->id = element.getAttributeValue("id");
- item->requirements = element.getAttributeValue("requirements");
- item->virtualNode = 0;
- return item;
- }
- bool QuestGraphItemElement::updateElement(Framework::XML::Element& element,
- Framework::Drawable& z,
- Framework::UIMLContainer& generalFactory)
- {
- return false;
- }
- void QuestGraphItemElement::layout(Framework::XML::Element& element,
- Framework::Drawable& z,
- int pWidth,
- int pHeight,
- Framework::UIMLContainer& generalLayouter)
- {
- UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter);
- }
- Connection::Connection(QuestGraphItem* zSource)
- : ReferenceCounter(),
- zSource(zSource),
- vx(0),
- minY(0),
- maxY(0)
- {}
- void Connection::renderVertical(Framework::Image& rObj)
- {
- if (targets.getEntryCount())
- {
- rObj.drawLineV(
- vx, minY, maxY - minY, isActive() ? 0xFFFFFFFF : 0xFF52525E);
- }
- }
- void Connection::renderHorizontal(Framework::Image& rObj)
- {
- if (targets.getEntryCount())
- {
- Framework::Point start = zSource->getPosition();
- start.x += zSource->getWidth();
- start.y += zSource->getHeight() / 2;
- rObj.drawLineH(start.x, start.y - 2, vx - start.x, 0xA0000000);
- rObj.drawLineH(start.x, start.y - 1, vx - start.x, 0xA0000000);
- rObj.drawLineH(start.x,
- start.y,
- vx - start.x,
- isActive() ? 0xFFFFFFFF : 0xFF52525E);
- rObj.drawLineH(start.x, start.y + 1, vx - start.x, 0xA0000000);
- rObj.drawLineH(start.x, start.y + 2, vx - start.x, 0xA0000000);
- for (const ConnectionTarget& target : targets)
- {
- Framework::Point end
- = target.zTarget->getTargetPosition(target.targetIndex);
- rObj.drawLineH(vx + 1, end.y - 2, end.x - vx - 1, 0xA0000000);
- rObj.drawLineH(vx + 1, end.y - 1, end.x - vx - 1, 0xA0000000);
- rObj.drawLineH(vx + 1,
- end.y,
- end.x - vx - 1,
- isActive() ? 0xFFFFFFFF : 0xFF52525E);
- rObj.drawLineH(vx + 1, end.y + 1, end.x - vx - 1, 0xA0000000);
- rObj.drawLineH(vx + 1, end.y + 2, end.x - vx - 1, 0xA0000000);
- }
- }
- }
- void Connection::setVx(int vx)
- {
- this->vx = vx;
- }
- void Connection::addConnectionTarget(ConnectionTarget target)
- {
- targets.add(target);
- }
- void Connection::setTargetIndex(AndNode* zTarget, int index)
- {
- for (auto target = targets.begin(); target; target++)
- {
- if (target.val().zTarget == zTarget)
- {
- target.set({index, target.val().zTarget});
- return;
- }
- }
- }
- void Connection::layout()
- {
- minY = 0;
- maxY = 0;
- bool start = 1;
- for (const ConnectionTarget& target : targets)
- {
- Framework::Point end
- = target.zTarget->getTargetPosition(target.targetIndex);
- if (start || end.y < minY)
- {
- minY = end.y;
- }
- if (start || end.y > maxY)
- {
- maxY = end.y;
- }
- start = 0;
- }
- Framework::Point origin = zSource->getPosition();
- origin.x += zSource->getWidth();
- origin.y += zSource->getHeight() / 2;
- if (minY > origin.y) minY = origin.y;
- if (maxY < origin.y) maxY = origin.y;
- maxY++;
- }
- bool Connection::isActive() const
- {
- return zSource->isFinished();
- }
- int Connection::getOrderNum() const
- {
- return zSource->getNodeIndex();
- }
- int Connection::getTargetCount() const
- {
- return targets.getEntryCount();
- }
- int Connection::getVerticalLength() const
- {
- return maxY - minY;
- }
- int Connection::getVx() const
- {
- return vx;
- }
- bool Connection::hasTarget(AndNode* zAndNode, int index) const
- {
- for (auto target : targets)
- {
- if (target.zTarget == zAndNode && target.targetIndex == index)
- {
- return true;
- }
- }
- return false;
- }
- AndNode::AndNode()
- : DrawableBackground()
- {
- setStyle(
- DrawableBackground::Style::Visible | DrawableBackground::Style::Border);
- setBorderWidth(1);
- setBorderColor(0xFF52525E);
- tr.setFontSize(12);
- tr.setFontZ(dynamic_cast<Font*>(uiFactory.initParam.font->getThis()));
- }
- void AndNode::addConnection(Connection* zConnection)
- {
- int pos = 0;
- for (Connection* other : connections)
- {
- if (other->getOrderNum() > zConnection->getOrderNum()) break;
- pos++;
- }
- zConnection->addConnectionTarget({pos, this});
- connections.add(zConnection, pos);
- pos = 0;
- for (Connection* con : connections)
- {
- con->setTargetIndex(this, pos);
- pos++;
- }
- }
- void AndNode::render(Framework::Image& rObj)
- {
- setBorderColor(isActive() ? 0xFFFFFFFF : 0xFF52525E);
- if (connections.getEntryCount() > 1)
- {
- DrawableBackground::render(rObj);
- if (rObj.setDrawOptions(pos.x + getBorderWidth(),
- pos.y + getBorderWidth(),
- getInnerWidth(),
- getInnerHeight()))
- {
- tr.renderText(getInnerWidth() / 2 - tr.getTextWidth("&") / 2,
- getInnerHeight() / 2 - tr.getTextHeight("&") / 2,
- "&",
- rObj,
- isActive() ? 0xFFFFFFFF : 0xFF52525E);
- rObj.releaseDrawOptions();
- }
- }
- else if (connections.getEntryCount() > 0)
- {
- if (rObj.setDrawOptions(pos, gr))
- {
- rObj.drawLineH(0,
- 0,
- gr.x,
- connections.get(0)->isActive() ? 0xFFFFFFFF : 0xFF52525E);
- rObj.releaseDrawOptions();
- }
- }
- }
- Framework::Point AndNode::getTargetPosition(int index)
- {
- if (connections.getEntryCount() == 1)
- {
- return pos;
- }
- return pos + Framework::Point(0, 10 + index * 11);
- }
- void AndNode::layout()
- {
- if (connections.getEntryCount() == 1)
- {
- setSize(20, 1);
- }
- else
- {
- setSize(20, 10 + connections.getEntryCount() * 11);
- }
- }
- bool AndNode::isActive() const
- {
- for (Connection* connection : connections)
- {
- if (!connection->isActive()) return false;
- }
- return connections.getEntryCount() > 0;
- }
- int AndNode::getConnectionCount() const
- {
- return connections.getEntryCount();
- }
- OrConnection::OrConnection(QuestGraphItem* zTarget,
- const Framework::Array<ConnectionInfo>& connections)
- : ReferenceCounter(),
- zTarget(zTarget),
- minY(0),
- maxY(0)
- {
- int currId = -1;
- AndNode* currNode = 0;
- for (const ConnectionInfo& info : connections)
- {
- if (info.id != currId)
- {
- currNode = new AndNode();
- andNodes.add(currNode);
- currId = info.id;
- }
- currNode->addConnection(info.target->zOutgoingConnection());
- }
- }
- void OrConnection::render(Framework::Image& rObj)
- {
- if (andNodes.getEntryCount() == 0) return;
- bool active = isActive();
- rObj.drawLineV(zTarget->getX() - 11,
- minY,
- maxY - minY,
- active ? 0xFFFFFFFF : 0xFF52525E);
- rObj.drawLineH(zTarget->getX() - 10,
- zTarget->getY() + zTarget->getHeight() / 2,
- 10,
- active ? 0xFFFFFFFF : 0xFF52525E);
- for (AndNode* node : andNodes)
- {
- rObj.drawLineH(node->getX() + node->getWidth(),
- node->getY() + node->getHeight() / 2,
- 10,
- active ? 0xFFFFFFFF : 0xFF52525E);
- node->render(rObj);
- }
- }
- void OrConnection::layout()
- {
- int nodeHeight = -10;
- for (AndNode* node : andNodes)
- {
- node->layout();
- nodeHeight += node->getHeight() + 10;
- }
- int y = zTarget->getY() + zTarget->getHeight() / 2 - nodeHeight / 2;
- bool start = 1;
- AndNode* last = 0;
- for (AndNode* node : andNodes)
- {
- node->setPosition(zTarget->getX() - 21 - node->getWidth(), y);
- if (start)
- {
- minY = y + node->getHeight() / 2;
- }
- y += node->getHeight() + 10;
- start = 0;
- last = node;
- }
- if (last)
- {
- y -= 10 + last->getHeight();
- maxY = y + last->getHeight() / 2 + 1;
- }
- else
- {
- maxY = minY + 1;
- }
- }
- int OrConnection::getNeededHeight() const
- {
- int minY = 0;
- int maxY = 0;
- bool first = 1;
- for (AndNode* node : andNodes)
- {
- if (first || node->getY() < minY)
- {
- minY = node->getY();
- }
- if (first || node->getY() + node->getHeight() > maxY)
- {
- maxY = node->getY() + node->getHeight();
- }
- first = 0;
- }
- return maxY - minY;
- }
- bool OrConnection::isActive() const
- {
- for (AndNode* node : andNodes)
- {
- if (node->isActive()) return 1;
- }
- return 0;
- }
- bool OrConnection::isHorizontalLineConflict(
- int y, Connection* zIgnoredIncommingConnection) const
- {
- for (AndNode* node : andNodes)
- {
- for (int i = 0; i < node->getConnectionCount(); i++)
- {
- if (!zIgnoredIncommingConnection
- || !zIgnoredIncommingConnection->hasTarget(node, i))
- {
- Point connection = node->getTargetPosition(i);
- if (abs(y - connection.y) < 5) return 1;
- }
- }
- }
- return 0;
- }
- QuestGraphItem::QuestGraphItem()
- : DrawableBackground(),
- layerIndex(-1),
- nodeIndex(-1),
- outgoingConnection(0),
- incommingConnection(0),
- finished(0),
- rewarded(0),
- mainQuest(0),
- virtualNode(0),
- animationProgress(0)
- {
- addStyle(
- DrawableBackground::Style::Visible | DrawableBackground::Style::Border
- | DrawableBackground::Style::Allowed | DrawableBackground::Style::BImage
- | DrawableBackground::Style::BImageScale
- | DrawableBackground::Style::BAlpha
- | DrawableBackground::Style::Background);
- setBorderColor(0xFF52525E);
- setBorderWidth(1);
- setMouseEvent(Framework::_ret1ME);
- }
- QuestGraphItem::~QuestGraphItem()
- {
- if (outgoingConnection) outgoingConnection->release();
- if (incommingConnection) incommingConnection->release();
- }
- bool QuestGraphItem::tick(double tickVal)
- {
- animationProgress += tickVal * 20;
- if (animationProgress > getWidth() * 2 + getHeight() * 2 - 4)
- {
- animationProgress -= getWidth() * 2 + getHeight() * 2 - 4;
- }
- rend = 1;
- return DrawableBackground::tick(tickVal);
- }
- int getBorderX(int p, int width, int height)
- {
- if (p < width)
- {
- return p;
- }
- else if (p < width + height - 1)
- {
- return width - 1;
- }
- else if (p < width * 2 + height - 2)
- {
- return width - (p - width - height + 2);
- }
- else
- {
- return 0;
- }
- }
- int getBorderY(int p, int width, int height)
- {
- if (p < width)
- {
- return 0;
- }
- else if (p < width + height - 1)
- {
- return p - width + 1;
- }
- else if (p < width * 2 + height - 2)
- {
- return height - 1;
- }
- else
- {
- return height - (p - width * 2 - height + 3);
- }
- }
- void QuestGraphItem::render(Framework::Image& rObj)
- {
- if (incommingConnection) incommingConnection->render(rObj);
- if (isVirtual())
- {
- rObj.drawLineH(
- pos.x, pos.y, gr.x, isFinished() ? 0xFFFFFFFF : 0xFF52525E);
- return;
- }
- DrawableBackground::render(rObj);
- if (finished && !rewarded)
- {
- if (rObj.setDrawOptions(pos.x, pos.y, gr.x, gr.y))
- {
- for (int i = 0; i < 7; i++)
- {
- int p
- = ((int)animationProgress + i) % (gr.x * 2 + gr.y * 2 - 4);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y) - 1,
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y) - 1,
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y) + 1,
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y) + 1,
- 0xFFFFFF00);
- p = ((int)animationProgress + i + gr.x - 1)
- % (gr.x * 2 + gr.y * 2 - 4);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y) - 1,
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y) - 1,
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y) + 1,
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y) + 1,
- 0xFFFFFF00);
- p = ((int)animationProgress + i + gr.x + gr.y - 2)
- % (gr.x * 2 + gr.y * 2 - 4);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y) - 1,
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y) - 1,
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y) + 1,
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y) + 1,
- 0xFFFFFF00);
- p = ((int)animationProgress + i + gr.x * 2 + gr.y - 3)
- % (gr.x * 2 + gr.y * 2 - 4);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y) - 1,
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y) - 1,
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y) + 1,
- getBorderY(p, gr.x, gr.y),
- 0xFFFFFF00);
- rObj.setPixelDP(getBorderX(p, gr.x, gr.y),
- getBorderY(p, gr.x, gr.y) + 1,
- 0xFFFFFF00);
- }
- rObj.releaseDrawOptions();
- }
- }
- }
- void QuestGraphItem::renderVerticalConnections(Framework::Image& rObj)
- {
- if (outgoingConnection) outgoingConnection->renderVertical(rObj);
- }
- void QuestGraphItem::renderHorizontalConnections(Framework::Image& rObj)
- {
- if (outgoingConnection) outgoingConnection->renderHorizontal(rObj);
- }
- void QuestGraphItem::replacePreviousConnections(
- QuestGraphItem* zBefore, QuestGraphItem* zAfter)
- {
- for (auto con = previousLayersConnections.begin(); con; con++)
- {
- if (con.val().target == zBefore) con.set({zAfter, con.val().id});
- }
- }
- const Framework::Text& QuestGraphItem::getId() const
- {
- return id;
- }
- const Framework::Text& QuestGraphItem::getRequirements() const
- {
- return requirements;
- }
- bool QuestGraphItem::calculateLaxerIndex()
- {
- int oldLayerIndex = layerIndex;
- int maxLayerIndex = -1;
- for (const ConnectionInfo& item : previousLayersConnections)
- {
- if (item.target->getLayerIndex() < 0) return 0;
- if (item.target->getLayerIndex() > maxLayerIndex)
- {
- maxLayerIndex = item.target->getLayerIndex();
- }
- }
- layerIndex = maxLayerIndex + 1;
- return oldLayerIndex != layerIndex;
- }
- int QuestGraphItem::getLayerIndex() const
- {
- return layerIndex;
- }
- void QuestGraphItem::setVirtual(bool virtualNode)
- {
- this->virtualNode = virtualNode;
- gr.y = virtualNode ? 1 : gr.y;
- gr.x = 1;
- setStyle(DrawableBackground::Style::Visible, virtualNode);
- }
- void QuestGraphItem::setNodeIndex(int index)
- {
- this->nodeIndex = index;
- }
- void QuestGraphItem::addNextLayerRef(ConnectionInfo zItem)
- {
- nextLayersConnections.add(zItem);
- }
- void QuestGraphItem::addPreviousLayerRef(ConnectionInfo zItem)
- {
- previousLayersConnections.add(zItem);
- }
- void QuestGraphItem::initializeConnections()
- {
- outgoingConnection = new Connection(this);
- incommingConnection = new OrConnection(this, previousLayersConnections);
- }
- const Framework::Array<ConnectionInfo>&
- QuestGraphItem::getNextLayersConnections() const
- {
- return nextLayersConnections;
- }
- int QuestGraphItem::getNodeIndex() const
- {
- return nodeIndex;
- }
- bool QuestGraphItem::isMainQuest() const
- {
- return mainQuest;
- }
- bool QuestGraphItem::isVirtual() const
- {
- return virtualNode;
- }
- bool QuestGraphItem::isFinished() const
- {
- return virtualNode ? incommingConnection->isActive() : finished;
- }
- Connection* QuestGraphItem::zOutgoingConnection() const
- {
- return outgoingConnection;
- }
- OrConnection* QuestGraphItem::zIncommingConnection() const
- {
- return incommingConnection;
- }
- QuestGraphItemLayer::QuestGraphItemLayer()
- : ReferenceCounter()
- {}
- bool QuestGraphItemLayer::tick(double tickVal)
- {
- bool result = 0;
- for (QuestGraphItem* item : items)
- {
- result |= item->tick(tickVal);
- }
- return result;
- }
- void QuestGraphItemLayer::render(Framework::Image& rObj)
- {
- for (QuestGraphItem* item : items)
- {
- item->render(rObj);
- item->renderVerticalConnections(rObj);
- }
- for (QuestGraphItem* item : items)
- {
- item->renderHorizontalConnections(rObj);
- }
- }
- void QuestGraphItemLayer::doMouseEvent(Framework::MouseEvent& me)
- {
- for (QuestGraphItem* item : items)
- {
- item->doPublicMouseEvent(me);
- }
- }
- void QuestGraphItemLayer::addItem(QuestGraphItem* item)
- {
- items.add(item);
- item->setNodeIndex(items.getEntryCount() - 1);
- }
- bool QuestGraphItemLayer::sortItems()
- {
- bool changed = 0;
- for (int index = 0; index < items.getEntryCount() - 1; index++)
- {
- QuestGraphItem* current = items.z(index);
- int conflicts = 0;
- int afterSwapConflicts = 0;
- QuestGraphItem* other = items.z(index + 1);
- for (const ConnectionInfo& connection :
- current->getNextLayersConnections())
- {
- for (const ConnectionInfo& otherConnection :
- other->getNextLayersConnections())
- {
- if ((otherConnection.target->getNodeIndex()
- < connection.target->getNodeIndex()))
- {
- conflicts++;
- }
- if ((otherConnection.target->getNodeIndex()
- > connection.target->getNodeIndex()))
- {
- afterSwapConflicts++;
- }
- }
- }
- if (conflicts > afterSwapConflicts)
- {
- // move node down
- QuestGraphItem* after = items.z(index + 1);
- after->setNodeIndex(index);
- current->setNodeIndex(index + 1);
- items.swap(index, index + 1);
- changed = 1;
- }
- }
- return changed;
- }
- int QuestGraphItemLayer::fixItemPositions(int x)
- {
- // calculate size needed for & nodes and | nodes
- int maxWidth = 0;
- for (QuestGraphItem* item : items)
- {
- item->initializeConnections();
- item->zIncommingConnection()->layout();
- if (item->getWidth() > maxWidth)
- {
- maxWidth = item->getWidth();
- }
- }
- x += 20 + 21; // ofset for incomming connections
- int y = 0;
- // calculate y positions of nodes
- for (QuestGraphItem* item : items)
- {
- int height = 0;
- int lastId = -1;
- int nodeHeight = item->zIncommingConnection()->getNeededHeight();
- if (nodeHeight < item->getHeight()) nodeHeight = item->getHeight();
- item->setPosition(x + maxWidth / 2 - item->getWidth() / 2,
- y + nodeHeight / 2 - item->getHeight() / 2);
- y += nodeHeight + 20;
- }
- x += maxWidth; // this layers node size
- for (QuestGraphItem* item : items)
- {
- item->zIncommingConnection()->layout();
- item->zOutgoingConnection()->setVx(x);
- item->zOutgoingConnection()->layout();
- }
- x += items.getEntryCount() * 11 + 10; // offset for outgoing connections
- return x + 20; // min space between layers
- }
- void QuestGraphItemLayer::sortConnections()
- {
- for (QuestGraphItem* item : items)
- {
- item->zIncommingConnection()->layout();
- item->zOutgoingConnection()->layout();
- }
- int connectionCount = 0;
- bool* sorted = new bool[items.getEntryCount()];
- memset(sorted, 0, sizeof(bool) * items.getEntryCount());
- int sortedCount = 0;
- while (true)
- {
- int minHeight = -1;
- QuestGraphItem* next = 0;
- for (QuestGraphItem* item : items)
- {
- if (sorted[item->getNodeIndex()]) continue;
- if (item->zOutgoingConnection()->getTargetCount()
- == connectionCount)
- {
- if (minHeight < 0
- || item->zOutgoingConnection()->getVerticalLength()
- < minHeight)
- {
- minHeight
- = item->zOutgoingConnection()->getVerticalLength();
- next = item;
- }
- }
- }
- if (!next)
- {
- if (sortedCount < items.getEntryCount())
- {
- connectionCount++;
- }
- else
- {
- break;
- }
- }
- else
- {
- next->zOutgoingConnection()->setVx(
- next->zOutgoingConnection()->getVx() + 10 + sortedCount * 11);
- sorted[next->getNodeIndex()] = 1;
- sortedCount++;
- }
- }
- delete[] sorted;
- }
- const Framework::RCArray<QuestGraphItem>& QuestGraphItemLayer::getItems() const
- {
- return items;
- }
- int QuestGraphItemLayer::getLeyerHeight(int& minY) const
- {
- minY = 0;
- int end = 0;
- bool first = 1;
- for (QuestGraphItem* item : items)
- {
- if (first || item->getY() < minY) minY = item->getY();
- if (first || item->getY() + item->getHeight() > end)
- end = item->getY() + item->getHeight();
- first = 0;
- }
- return end - minY;
- }
- int QuestGraphItemLayer::getLeyerHeight() const
- {
- int y;
- return getLeyerHeight(y);
- }
- void QuestGraphItemLayer::centerVertically(int pos)
- {
- int minY = 0;
- int height = getLeyerHeight(minY);
- int yOffset = pos - height / 2 - minY;
- for (QuestGraphItem* item : items)
- {
- item->setPosition(item->getX(), item->getY() + yOffset);
- item->zIncommingConnection()->layout();
- item->zOutgoingConnection()->layout();
- }
- }
- void QuestGraphItemLayer::resolveHorizontalConflicts(
- const QuestGraphItemLayer* zNextLayer)
- {
- for (QuestGraphItem* item : items)
- {
- int outgoingY = item->getY() + item->getHeight() / 2;
- if (zNextLayer->isHorizontalLineConflict(
- outgoingY, item->zOutgoingConnection()))
- {
- int offset = 0;
- for (int i = 1; i <= 10; i++)
- {
- if (!zNextLayer->isHorizontalLineConflict(
- outgoingY - i, item->zOutgoingConnection()))
- {
- offset = -i;
- break;
- }
- if (!zNextLayer->isHorizontalLineConflict(
- outgoingY + i, item->zOutgoingConnection()))
- {
- offset = i;
- break;
- }
- }
- item->setPosition(item->getX(), item->getY() + offset);
- item->zIncommingConnection()->layout();
- item->zOutgoingConnection()->layout();
- }
- }
- }
- bool QuestGraphItemLayer::isHorizontalLineConflict(
- int y, Connection* zIgnoredIncommingConnection) const
- {
- for (QuestGraphItem* item : items)
- {
- if (item->zIncommingConnection()->isHorizontalLineConflict(
- y, zIgnoredIncommingConnection))
- return 1;
- }
- return 0;
- }
- QuestGraph::QuestGraph()
- : DrawableBackground()
- {
- addStyle(DrawableBackground::Style::Visible
- | DrawableBackground::Style::Allowed
- | DrawableBackground::Style::Border);
- setBorderWidth(1);
- setBorderColor(0xFF52525E);
- setMouseEvent(Framework::_ret1ME);
- }
- bool QuestGraph::tick(double tickVal)
- {
- for (QuestGraphItemLayer* layer : layers)
- {
- rend |= layer->tick(tickVal);
- }
- return DrawableBackground::tick(tickVal);
- }
- void QuestGraph::render(Framework::Image& rObj)
- {
- if (hasStyle(DrawableBackground::Style::Visible)
- && layers.getEntryCount() > 0)
- {
- DrawableBackground::render(rObj);
- if (rObj.setDrawOptions(pos, gr))
- {
- if (rObj.setDrawOptions(getBorderWidth(),
- getBorderWidth(),
- getInnerWidth(),
- getInnerHeight()))
- {
- int hScrollOffset = 0;
- if (hasStyle(DrawableBackground::Style::HScroll)
- && horizontalScrollBar)
- {
- hScrollOffset = horizontalScrollBar->getScroll();
- }
- int vScrollOffset = 0;
- if (hasStyle(DrawableBackground::Style::VScroll)
- && vertikalScrollBar)
- {
- vScrollOffset = vertikalScrollBar->getScroll();
- }
- if (hScrollOffset || vScrollOffset)
- {
- rObj.addScrollOffset(hScrollOffset, vScrollOffset);
- }
- for (QuestGraphItemLayer* layer : layers)
- {
- layer->render(rObj);
- }
- rObj.releaseDrawOptions();
- }
- rObj.releaseDrawOptions();
- }
- }
- }
- void QuestGraph::doMouseEvent(Framework::MouseEvent& me, bool userRet)
- {
- userRet &= hasStyle(DrawableBackground::Style::Visible);
- bool vera = me.processed;
- if (!userRet)
- {
- me.processed = 1;
- }
- for (QuestGraphItemLayer* layer : layers)
- {
- layer->doMouseEvent(me);
- }
- if (!userRet)
- {
- me.processed = vera;
- }
- }
- void QuestGraph::addVirtualConnectionNodes()
- {
- int layerIndex = 0;
- // add virtual items for connections that do not go directly to the next
- // layer after this operation each node only have connections to the
- // immediate following layer
- for (QuestGraphItemLayer* layer : layers)
- {
- for (int i = 0; i < layer->getItems().getEntryCount(); i++)
- {
- QuestGraphItem* item = layer->getItems().z(i);
- auto iterator = item->getNextLayersConnections().begin();
- QuestGraphItem* virtualItem = 0;
- while (iterator)
- {
- if (iterator.val().target->getLayerIndex() > layerIndex + 1)
- {
- if (!virtualItem)
- {
- virtualItem = new QuestGraphItem();
- virtualItem->addPreviousLayerRef(
- {item, iterator.val().id});
- virtualItem->addNextLayerRef(
- {iterator.val().target, iterator.val().id});
- iterator.val().target->replacePreviousConnections(
- item, virtualItem);
- virtualItem->setVirtual(true);
- virtualItem->calculateLaxerIndex();
- iterator.set({virtualItem, iterator.val().id});
- iterator++;
- }
- else
- {
- virtualItem->addNextLayerRef(
- {iterator.val().target, iterator.val().id});
- iterator.val().target->replacePreviousConnections(
- item, virtualItem);
- iterator.remove();
- }
- }
- else if (iterator.val().target->getLayerIndex() < 0)
- { // remove connections to invalid nodes
- iterator.remove();
- }
- else
- {
- iterator++;
- }
- }
- if (virtualItem)
- {
- addItem(virtualItem);
- }
- }
- layerIndex++;
- }
- }
- void QuestGraph::sortItems()
- {
- bool changed = 1;
- while (changed)
- {
- changed = 0;
- for (QuestGraphItemLayer* layer : layers)
- {
- changed |= layer->sortItems();
- }
- }
- }
- void QuestGraph::fixItemPositions()
- {
- int height = 0;
- int x = 0;
- for (QuestGraphItemLayer* layer : layers)
- {
- x = layer->fixItemPositions(x);
- if (layer->getLeyerHeight() > height)
- {
- height = layer->getLeyerHeight();
- }
- }
- for (QuestGraphItemLayer* layer : layers)
- {
- layer->sortConnections();
- }
- if (height > getInnerHeight())
- {
- addStyle(DrawableBackground::Style::VScroll);
- setVerticalClickScroll(10);
- vertikalScrollBar->update(height, getInnerHeight());
- }
- if (layers.getEntryCount() * 150 - 80 > getInnerWidth())
- {
- addStyle(DrawableBackground::Style::HScroll);
- setHorizontalClickScroll(10);
- horizontalScrollBar->update(
- layers.getEntryCount() * 150 - 80, getInnerWidth());
- }
- QuestGraphItemLayer* last = 0;
- for (int i = layers.getEntryCount() - 1; i >= 0; i--)
- {
- QuestGraphItemLayer* layer = layers.z(i);
- layer->centerVertically(getHeight() / 2);
- if (last) layer->resolveHorizontalConflicts(last);
- last = layer;
- }
- }
- void QuestGraph::centerVertically()
- {
- int height = 0;
- for (QuestGraphItemLayer* layer : layers)
- {
- if (layer->getLeyerHeight() > height)
- {
- height = layer->getLeyerHeight();
- }
- }
- if (height > getInnerHeight())
- {
- addStyle(DrawableBackground::Style::VScroll);
- setVerticalClickScroll(10);
- vertikalScrollBar->update(height, getInnerHeight());
- }
- if (layers.getEntryCount() * 150 - 80 > getInnerWidth())
- {
- addStyle(DrawableBackground::Style::HScroll);
- setHorizontalClickScroll(10);
- horizontalScrollBar->update(
- layers.getEntryCount() * 150 - 80, getInnerWidth());
- }
- QuestGraphItemLayer* last = 0;
- for (int i = layers.getEntryCount() - 1; i >= 0; i--)
- {
- QuestGraphItemLayer* layer = layers.z(i);
- layer->centerVertically(getHeight() / 2);
- if (last) layer->resolveHorizontalConflicts(last);
- last = layer;
- }
- }
- void QuestGraph::addItem(QuestGraphItem* item)
- {
- int layerInex = item->getLayerIndex();
- if (layerInex >= 0)
- {
- while (layerInex >= layers.getEntryCount())
- {
- layers.add(new QuestGraphItemLayer());
- }
- layers.z(layerInex)->addItem(item);
- }
- else
- {
- invalidNodes.addItem(item);
- }
- }
|