Exemplo n.º 1
0
POI *Mystery::parsePOINode(xmlNode *node) {

    POI *poi = new POI();

    int x = atoi(xmlGetAttribute(node, "positionX"));
    int y = atoi(xmlGetAttribute(node, "positionY"));
    int interest = atoi(xmlGetAttribute(node, "interest"));

    poi->position = pointMake(x, y);
    poi->interest = (Interest) interest;
    poi->description = xmlGetAttribute(node, "description");
    poi->shortDescription = poi->description;

    if (xmlGetAttribute(node, "shortDescription") != NULL) {
        poi->shortDescription = xmlGetAttribute(node, "shortDescription");
    }

    poi->visualPosition = poi->position;

    if (xmlGetAttribute(node, "visualPositionX") != NULL) {
        int vx = atoi(xmlGetAttribute(node, "visualPositionX"));
        int vy = atoi(xmlGetAttribute(node, "visualPositionY"));
        poi->visualPosition = pointMake(vx, vy);
    }

    poi->contents = NULL;
    poi->searchedByMurderer = false;

    return poi;
}
void InvestigationScene::questionWhen() {
    
    removeQuestionElements();
    
    std::string question;
    
    if (currentFilter.strange) {
        
        question = "Did anything strange happen";
        
    } else if (currentFilter.where == NULL) {
        
        question = "Where ";
        
        if (currentFilter.who == activeCharacter) {
            question.append("were you");
        } else {
            question.append("was ");
            question.append(currentFilter.who->name);
        }
        
    } else if (currentFilter.who == NULL) {
        
        question = "Who was in the ";
        question.append(currentFilter.where->name);
    }
    
    question.append(" between ... ?");
    
    questionLabel->setText(question.c_str());
    
    Button *button = new Button("<", fontBig, BTN_TXT_COLOR, "res/btn_small.png", "res/btn_small_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(260, 300));
    button->setTag(401);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
    
    button = new Button(">", fontBig, BTN_TXT_COLOR, "res/btn_small.png", "res/btn_small_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(540, 300));
    button->setTag(402);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
    
    char buff[20];
    sprintf(buff, "%s and %s", timeToString(currentFilter.timeStart + START_TIME, false).c_str(), timeToString(currentFilter.timeEnd + START_TIME, false).c_str());
    
    whenLabel->setText(buff);
    whenLabel->setVisible(true);
    
    askQuestionButton->setEnabled(true);
    askQuestionButton->setVisible(true);
}
Exemplo n.º 3
0
void Camera::setCenter(Point c) {
    
    float cx = c.x;
    float cy = c.y;
    
    float centerX = center.x;
    float centerY = center.y;
    
    if ((cx + (viewportSize.width / 2)) > boundsSize.width) {
        centerX = boundsSize.width - (viewportSize.width / 2);
    } else if ((cx - (viewportSize.width / 2)) < 0) {
        centerX = viewportSize.width / 2;
    } else {
        centerX = cx;
    }
    
    if ((cy + (viewportSize.height / 2)) > boundsSize.height) {
        centerY = boundsSize.height - (viewportSize.height / 2);
    } else if ((cy - (viewportSize.height / 2)) < 0) {
        centerY = viewportSize.height / 2;
    } else {
        centerY = cy;
    }
    
    center = pointMake(centerX, centerY);
}
//Welzl algorithm
void minimumCircle(float* radius, Point* position, Point* points,int size){

	if(size == 0){
		*radius = 0;
		*position = pointMake(0, 0);
		return;
	}
	
	size--;
	Point* evaluationPoint = &points[size];
	
	minimumCircle(radius, position, points, size);
	
	if(isPointInsideCircle(*evaluationPoint, *radius, *position)){
		return;
	}
	
	Point* P = copyPoints(size, points);
	Point* R = copyPoints(1, evaluationPoint);

	minimumDisk(P, R, size, 1, radius, position);
	
	free(P);
	free(R);
	
	return;
	
}
Exemplo n.º 5
0
Point Camera::getTop() {
    
    float cx = center.x - (viewportSize.width / 2);
    float cy = center.y - (viewportSize.height / 2);
    
    return pointMake(cx, cy);
}
Exemplo n.º 6
0
Camera::Camera(int vw, int vh, int bw, int bh) {
    
    viewportSize = sizeMake(vw, vh);
    
    boundsSize = sizeMake(bw, bh);
    
    center = pointMake(0, 0);
}
State physicsResolution(PhysicsObject*a, PhysicsObject*b, CollisionPair pair){
	//first we find the impulse in our collision
	float impulse;
	
	Point centerA = worldPosition(a->rotationCenter, *a);
	Point centerB = worldPosition(b->rotationCenter, *b);
	Point RA = pointMake(pair.location.x-centerA.x, pair.location.y-centerA.y);
	Point RB = pointMake(pair.location.x-centerB.x, pair.location.y-centerB.y);
	
	Vector VAP = pointMake(a->linearVelocity.x-a->angularVelocity*RA.y, a->linearVelocity.y+a->angularVelocity*RA.x);
	Vector VBP = pointMake(b->linearVelocity.x-b->angularVelocity*RB.y, b->linearVelocity.y+b->angularVelocity*RB.x);
	Vector VAB = pointMake(VAP.x - VBP.x, VAP.y - VBP.y);
	
	float crossRANsquare = RA.x*pair.normal.y-pair.normal.x*RA.y;
	crossRANsquare = crossRANsquare*crossRANsquare;
	float crossRBNsquare = RB.x*pair.normal.y-pair.normal.x*RB.y;
	crossRBNsquare = crossRBNsquare*crossRBNsquare;
	
	impulse = a->inverseMass + b->inverseMass + a->inverseInertia*crossRANsquare + b->inverseInertia*crossRBNsquare;
	impulse = -(1+RESTITUTION_COEFFCIENT)*(VAB.x*pair.normal.x+VAB.y*pair.normal.y)/impulse;
	
	
	State DeltaState;
	DeltaState.deltaVel = pointMake(impulse*a->inverseMass*pair.normal.x,impulse*a->inverseMass*pair.normal.y);
	DeltaState.deltaAngVel = (RA.x*pair.normal.y-RA.y*pair.normal.x)*a->inverseInertia*impulse;
	
	float deltaPosModule = a->inverseMass*pair.depth/(a->inverseMass+b->inverseMass);
	DeltaState.deltaPosition = pointMake(deltaPosModule*pair.normal.x, deltaPosModule*pair.normal.y);
	
	return DeltaState;
}
//Welzl final recursion - calculates the actual circle
void minimumDisk(Point* P, Point* R, int sizeP, int sizeR, float* radius, Point* position){
	
	if(sizeP==0 || sizeR==3){
		if(sizeR==1){
			*radius = 0;
			*position = R[0];
			return;
		}
		if(sizeR==2){
			*position = pointMake((R[0].x+R[1].x)/2., (R[0].y+R[1].y)/2.);
			*radius = pointsDistance(R[0], R[1])/2.;
			return;
		}
		if(sizeR==3){
			
			Point P1 = pointMake((R[0].x+R[1].x)/2., (R[0].y+R[1].y)/2.);
			Point AB = pointMake((R[1].x-R[0].x)/2., (R[1].y-R[0].y)/2.);
			Point BC = pointMake((R[2].x-R[1].x)/2., (R[2].y-R[1].y)/2.);
			Point AC = pointMake((R[2].x-R[0].x)/2., (R[2].y-R[0].y)/2.);
			Point PR = pointMake(-AB.y,AB.x);
			
			float w = -1./2.*(BC.x*AC.x+BC.y*AC.y)/(BC.x*AB.y-BC.y*AB.x);
			
			*position = pointMake(P1.x+w*PR.x, P1.y+w*PR.y);
			
			*radius = pointsDistance(*position, R[0]);
			
			return;
		}
	}
	
	Point* P2 = copyPoints(sizeP, P);
	Point* R2 = copyPoints(sizeR, R);
	
	
	sizeP--;
	Point point = P[sizeP];

	minimumDisk(P2, R2, sizeP, sizeR, radius, position);
	
	if(isPointInsideCircle(point, *radius, *position)){
		free(R2);
		free(P2);
		return;
	}
	
	
	R2[sizeR] = point;
	
	sizeR++;
	
	minimumDisk(P2, R2, sizeP, sizeR, radius, position);
	
	free(R2);
	free(P2);
	return;
	
	
}
Point worldPosition(Point point, PhysicsObject object){
	
	float c1 = TS8_cos(object.rotation);
	float s1 = TS9_sin(object.rotation);
	float offsetx = object.rotationCenter.x*(1-c1)+object.rotationCenter.y*s1+object.position.x;
	float offsety = object.rotationCenter.y*(1-c1)-object.rotationCenter.x*s1+object.position.y;
	
	return pointMake(c1*point.x-s1*point.y+offsetx, s1*point.x+c1*point.y+offsety);
	
}
Exemplo n.º 10
0
void InvestigationScene::questionWhere() {
    
    removeQuestionElements();
    
    questionLabel->setText("Where was ... ?");
    
    std::vector<Character *> characters = mystery->getCharacters();
    std::vector<Character *>::iterator it;
    
    int i = 0;
    
    int px = 400;
    int py = 200;
    
    for (it = characters.begin(); it < characters.end(); ++it) {
        
        Character *character = (Character *) *it;
        
        std::string name = character->name;
        if (character == activeCharacter) {
            name = "You";
        }
        
        Button *button = new Button(name.c_str(), font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
        button->setZOrder(504);
        button->setAnchorPoint(pointMake(0.5, 0.5));
        button->setPosition(pointMake(px, py));
        button->setTag(301 + i);
        button->data = character;
        button->setHandler(this);
        
        addToDisplayList(button);
        questionElements.push_back(button);
        
        py += 36;
        
        i++;
    }
}
Exemplo n.º 11
0
void InvestigationScene::questionWho() {
    
    removeQuestionElements();
    
    questionLabel->setText("Who was in the ... ?");
    
    std::vector<Room *> rooms = mystery->getRooms();
    std::vector<Room *>::iterator it;
    
    int i = 0;
    
    int px = 300;
    int py = 200;
    
    for (it = rooms.begin(); it < rooms.end(); ++it) {
        
        Room *room = (Room *) *it;
        
        Button *button = new Button(room->name.c_str(), font, BTN_TXT_COLOR, "res/btn_med.png", "res/btn_med_pressed.png");
        button->setZOrder(504);
        button->setAnchorPoint(pointMake(0.5, 0.5));
        button->setPosition(pointMake(px, py));
        button->setTag(201 + i);
        button->data = room;
        button->setHandler(this);
        
        addToDisplayList(button);
        questionElements.push_back(button);
        
        py += 36;
        
        if (i == 6) {
            py = 200;
            px += 192;
        }
        
        i++;
    }
}
Exemplo n.º 12
0
bool InvestigationScene::tick(double dt) {
    
    if (inputLocked) {
        return true;
    }
    
    int tx = playerSprite->getPosition().x / collision->getTileSize().width;
    int ty = playerSprite->getPosition().y / collision->getTileSize().height;
    
    std::vector<Room *> rooms = mystery->getRooms();
    std::vector<Room *>::iterator itRooms;
    for (itRooms = rooms.begin(); itRooms < rooms.end(); ++itRooms) {
        Room *room = (Room *) *itRooms;
        
        if (rectContainsPoint(room->bounds, pointMake(tx, ty)) && room != currentRoom) {
            currentRoom = room;
            currentRoomLabel->setText(room->name.c_str());
        }
    }
    
    float dx = 0;
    float dy = 0;
    
    bool isMoving = !pointEqualsIntegral(moving, pointMake(0, 0));
    
    if (isMoving) {
        
        dx = moving.x * 200 * dt;
        dy = moving.y * 200 * dt;
        
        if (dy < 0) {
            moveDir = 0;
        } else if (dy > 0) {
            moveDir = 18;
        } else if (dx < 0) {
            moveDir = 9;
        } else if (dx > 0) {
            moveDir = 27;
        }
        
        curFrame += dt * 10;
        if (curFrame > 8) curFrame -= 8;
        
    } else {
        
        curFrame = 0;
    }
    
    bool collided = false;
    
    Rect colRect = rectMake(playerSprite->getPosition().x - 16, playerSprite->getPosition().y - 16, 32, 32);
    
    Rect colRectX = rectOffset(colRect, dx, 0);
    Rect colRectY = rectOffset(colRect, 0, dy);
    
    int tw = collision->getTileSize().width;
    int th = collision->getTileSize().height;
    
    int tpx = playerSprite->getPosition().x / collision->getTileSize().width;
    int tpy = playerSprite->getPosition().y / collision->getTileSize().height;
    
    for (int j = tpy - 2; j <= tpy + 2; j++) {
        for (int i = tpx - 2; i <= tpx + 2; i++) {
            
            if (i >= 0 && i < collision->getSize().width && j >= 0 && j < collision->getSize().height) {
                int gid = collision->getTileAt(i, j);
                
                if (gid != 0) {
                    
                    Rect tileRect = rectMake(i * tw, j * th, tw, th);
                    
                    if (rectIntersectsRect(colRectX, tileRect)) {
                        dx = 0;
                        collided = true;
                    }
                    
                    if (rectIntersectsRect(colRectY, tileRect)) {
                        dy = 0;
                        collided = true;
                    }
                }
            }
        }
    }
    
    actionButton->setVisible(false);
    actionButton->setEnabled(false);
    
    activeCharacter = NULL;
    activePOI = NULL;
    
    std::vector<Character *> characters = mystery->getCharacters();
    std::vector<Character *>::iterator it;
    
    for (it = characters.begin(); it < characters.end(); ++it) {
        
        Character *character = (Character *) *it;
        
        std::string action;
        
        if (character->dead) {
            action.append("Look at ");
        } else {
            action.append("Talk to ");
        }
        
        action.append(character->name);
        
        Drawable *sprite = getByTag(character->tag);
        
        Rect otherColRect = rectMake(sprite->getPosition().x - 16, sprite->getPosition().y - 16, 32, 32);
        
        if (rectIntersectsRect(colRect, otherColRect)) {
            actionButton->setLabelText(action.c_str());
            actionButton->setPosition(pointMake(sprite->getPosition().x, sprite->getPosition().y - 32));
            actionButton->setVisible(true);
            actionButton->setEnabled(true);
            
            activeCharacter = character;
        }
    }
    
    if (currentRoom != NULL) {
        
        std::vector<POI *> POIList = currentRoom->pointsOfInterest;
        std::vector<POI *>::iterator itPOI;
        
        for (itPOI = POIList.begin(); itPOI < POIList.end(); ++itPOI) {
            
            POI *poi = (POI *) *itPOI;
            
            Rect tileRect = collision->getTileRect(poi->position.x, poi->position.y);
            tileRect = rectExpand(tileRect, 4, 4);
            
            if ((poi->interest == InterestContainerVisible || poi->interest == InterestContainerConceiled) && rectIntersectsRect(colRect, tileRect)) {
                
                std::string action = "Examine ";
                action.append(poi->shortDescription);
                
                actionButton->setLabelText(action.c_str());
                actionButton->setPosition(rectMidPoint(tileRect));
                actionButton->setVisible(true);
                actionButton->setEnabled(true);
                
                activePOI = poi;
            }
        }
    }
    
    playerSprite->setFrame(moveDir + (int)curFrame + (isMoving ? 1 : 0));
    playerSprite->setPosition(pointOffset(playerSprite->getPosition(), dx, dy));
    
    camera->setCenter(playerSprite->getPosition());
    
    return !endScene;
}
Exemplo n.º 13
0
Mystery::Mystery(const char *file, unsigned int seed, short *collisionData, int mapWidth, int mapHeight) {

    srand(seed);

    corpseFound = false;
    ended = false;

    this->mapWidth = mapWidth;
    this->mapHeight = mapHeight;
    this->mapData = collisionData;

    Room *firstRoom = NULL;

    xmlDoc *doc = xmlReadFile(file, NULL, 0);

    xmlNode *root = xmlDocGetRootElement(doc);

    std::vector<xmlNode *> roomNodes = xmlGetChildrenForName(root, "room");
    std::vector<xmlNode *>::iterator it;

    for (it = roomNodes.begin(); it < roomNodes.end(); ++it) {

        xmlNode *roomNode = (xmlNode *) *it;

        Room *room = new Room();
        room->name = xmlGetAttribute(roomNode, "name");

        int ox = atoi(xmlGetAttribute(roomNode, "boundsOriginX"));
        int oy = atoi(xmlGetAttribute(roomNode, "boundsOriginY"));
        int w = atoi(xmlGetAttribute(roomNode, "boundsWidth"));
        int h = atoi(xmlGetAttribute(roomNode, "boundsHeight"));

        room->bounds = rectMake(ox, oy, w, h);

        if (xmlGetAttribute(roomNode, "firstRoom") != NULL) {
            firstRoom = room;
        }

        std::vector<xmlNode *> POINodes = xmlGetChildrenForName(roomNode, "pointOfInterest");
        std::vector<xmlNode *>::iterator itPOI;

        for (itPOI = POINodes.begin(); itPOI < POINodes.end(); itPOI++) {

            xmlNode *POInode = (xmlNode *) *itPOI;

            POI *poi = parsePOINode(POInode);
            room->pointsOfInterest.push_back(poi);
        }

        rooms.push_back(room);
    }

    std::vector<xmlNode *> weaponNodes = xmlGetChildrenForName(root, "weapon");

    for (it = weaponNodes.begin(); it < weaponNodes.end(); ++it) {

        xmlNode *weaponNode = (xmlNode *) *it;

        POI *weapon = parsePOINode(weaponNode);

        POI *container;
        Room *room;

        do {

            int idx = rand() % rooms.size();
            room = rooms[idx];

            std::vector<POI *> containers = room->getPointsOfInterest(InterestContainerVisible, false);

            if (containers.size() > 0) {

                idx = rand() % containers.size();
                container = containers[idx];
            } else {
                container = NULL;
            }

        } while (container == NULL || container->contents != NULL);


        container->contents = weapon;
        weapon->position = container->visualPosition;

        if (container->interest == InterestContainerConceiled) {
            weapon->position = pointMake(-20, -20);
        }

        weapons.push_back(weapon);

        printf("%s is in the %s in the %s\n", weapon->description.c_str(), container->description.c_str(), room->name.c_str());
    }

    crimeWeapon = NULL;

    std::vector<xmlNode *> charNodes = xmlGetChildrenForName(root, "character");

    int i = 1;

    for (it = charNodes.begin(); it < charNodes.end(); ++it) {

        xmlNode *charNode = (xmlNode *) *it;

        Character *character = parseCharacterNode(charNode);

        character->tag = i;
        character->interest = (Interest) (rand() % InterestContainerVisible);
        character->position = pointMake(i + 35, 50);
        character->currentRoom = firstRoom;
        character->idle = true;
        character->currentTarget = NULL;
        character->murderTarget = NULL;
        character->carryingWeapon = NULL;
        character->conversationInterval = CONVERSATION_INTERVAL;
        character->dead = false;

        const char *strInt = NULL;

        switch (character->interest) {
        case InterestBooks:
            strInt = "books";
            break;
        case InterestPottery:
            strInt = "pottery";
            break;
        case InterestPaintings:
            strInt = "paintings";
            break;
        default:
            break;
        }

        printf("%s interested in %s\n", character->name.c_str(), strInt);

        characters.push_back(character);

        i++;
    }

    int murderTargetIdx = rand() % characters.size();
    victim = characters[murderTargetIdx];

    printf("*** %s is the murder target! ***\n", victim->name.c_str());

    do {

        int murdererIdx = rand() % characters.size();
        murderer = characters[murdererIdx];

    } while (murderer == victim);

    int weaponInterest = InterestWeaponCutting + rand() % 3;
    murderer->weaponInterest = (Interest) weaponInterest;
    murderer->timeBeforeSearchWeapon = rand() % MAX_DURATION_BEFORE_SEARCH_WEAPON + MIN_DURATION_BEFORE_SEARCH_WEAPON;
    murderer->timeBeforeTryMurder = rand() % MAX_DURATION_BEFORE_TRY_MURDER + MIN_DURATION_BEFORE_TRY_MURDER;

    printf("*** %s is the murderer! ***\n", murderer->name.c_str());
    murderer->murderTarget = victim;

    time = 0;
}
State collideObjects(PhysicsObject* a, PhysicsObject* b){
	State state;
	state.deltaAngVel = 0;
	state.deltaPosition = pointMake(0, 0);
	state.deltaVel = pointMake(0, 0);
	
	CollisionPair pairs[2*PHYSICS_OBJECT_MAXIMUM_POINTS];
	if(!coarseCollision(a, b)){
		return state;
	}
	
	//if a coarse collision happened, we will search for a refined one in each of A's edges.
	//in this step we try to find every point where B has hitted A and A has hitted B
	int Acurrent, Anext, Abefore, Bcurrent, Bnext, pairCount=0;
	
	//first case---------------------------------------------------------------------------
	/* 
	 PA1     PA3
	 \      /
	  \    /
  PB2---------PB1
	    \/
		PA2
	 
	V=A --=B
	*/
	for (Acurrent=0; Acurrent<a->format.polygonInfo.count; Acurrent++) {
		/*Given 3 sequenced vertex, we create two vectors, one from the
		 first to the second vertex and other from the second to the
		 third vertex.*/
		Anext = Acurrent==a->format.polygonInfo.count-1?0:Acurrent+1;
		Abefore = Acurrent==0?a->format.polygonInfo.count-1:Acurrent-1;
		Point PA1 = worldPosition(a->format.polygonInfo.points[Abefore],*a);
		Point PA2 = worldPosition(a->format.polygonInfo.points[Acurrent],*a);
		Point PA3 = worldPosition(a->format.polygonInfo.points[Anext],*a);
		Vector A1 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y);
		Vector A2 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y);

		pairs[pairCount].depth = 0;
		pairs[pairCount].normal = pointMake(0, 0);
		for (Bcurrent = 0; Bcurrent<b->format.polygonInfo.count; Bcurrent++) {
			/*for each edge of B, we will find if any of the edges are hitted by both
			 edges defined before, if thats the case, then A hitted B on that point
			 If both edges of A hitted more than one edge of B, we will keep the highest
			 depth*/
			Bnext = Bcurrent==b->format.polygonInfo.count-1?0:Bcurrent+1;
			Point PB1 = worldPosition(b->format.polygonInfo.points[Bcurrent], *b);
			Point PB2 = worldPosition(b->format.polygonInfo.points[Bnext], *b);
			Vector B = pointMake(PB2.x-PB1.x, PB2.y-PB1.y);
			Vector I1 = pointMake(PB1.x-PA1.x, PB1.y-PA1.y);
			Vector I2 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y);
			
			float crossBI1 = B.x*I1.y-B.y*I1.x;
			float crossBI2 = B.x*I2.y-B.y*I2.x;
			float crossAI1 = A1.x*I1.y-A1.y*I1.x;
			float crossAI2 = A2.x*I2.y-A2.y*I2.x;
			float crossBA1 = B.x*A1.y-B.y*A1.x;
			float crossBA2 = B.x*A2.y-B.y*A2.x;
			
			crossBA1=crossBA1==0?0.0001:crossBA1;
			crossBA2=crossBA2==0?0.0001:crossBA2;
			
			float t1 = crossAI1/crossBA1;
			float w1 = crossBI1/crossBA1;
			float t2 = crossAI2/crossBA2;
			float w2 = crossBI2/crossBA2;
			
			if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){
				//we do have a collision
				
				Vector normal = rotateVector(B, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside
				normalizePoint(&normal);
				Point collisionPoint=pointMake(((PA1.x+w1*A1.x)+(PA2.x+w2*A2.x))*0.5, ((PA1.y+w1*A1.y)+(PA2.y+w2*A2.y))*0.5);
				float depth = (PA2.x-collisionPoint.x)*normal.x+(PA2.y-collisionPoint.y)*normal.y;
				depth = -depth;
				if(Fabs(depth)>Fabs(pairs[pairCount].depth)){
					pairs[pairCount].depth = depth;
					pairs[pairCount].normal = normal;
					pairs[pairCount].location=collisionPoint;
				}
			}
		}
		if(Fabs(pairs[pairCount].depth)>0){
			pairCount++;
		}
	}
	
	//second case---------------------------------------------------------------------------
	/*
	 PA1     PA3
	 \      /
	  \    /
  PB2---------PB1
	    \/
		PA2
	 
	 V=B --=A
	 */
	//Although we did not change the names, A variables now refers to B while B variables refer to A
	for (Acurrent=0; Acurrent<b->format.polygonInfo.count; Acurrent++) {
		/*Given 3 sequenced vertex, we create two vectors, one from the
		 first to the second vertex and other from the second to the
		 third vertex.*/
		Anext = Acurrent==b->format.polygonInfo.count-1?0:Acurrent+1;
		Abefore = Acurrent==0?b->format.polygonInfo.count-1:Acurrent-1;
		Point PA1 = worldPosition(b->format.polygonInfo.points[Abefore],*b);
		Point PA2 = worldPosition(b->format.polygonInfo.points[Acurrent],*b);
		Point PA3 = worldPosition(b->format.polygonInfo.points[Anext],*b);
		Vector A1 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y);
		Vector A2 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y);
		
		pairs[pairCount].depth = 0;
		pairs[pairCount].normal = pointMake(0, 0);
		for (Bcurrent = 0; Bcurrent<a->format.polygonInfo.count; Bcurrent++) {
			/*for each edge of A, we will find if any of the edges are hitted by both
			 edges defined before, if thats the case, then A hitted B on that point
			 If both edges of B hitted more than one edge of A, we will keep the highest
			 depth*/
			Bnext = Bcurrent==a->format.polygonInfo.count-1?0:Bcurrent+1;
			Point PB1 = worldPosition(a->format.polygonInfo.points[Bcurrent], *a);
			Point PB2 = worldPosition(a->format.polygonInfo.points[Bnext], *a);
			Vector B = pointMake(PB2.x-PB1.x, PB2.y-PB1.y);
			Vector I1 = pointMake(PB1.x-PA1.x, PB1.y-PA1.y);
			Vector I2 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y);
			
			float crossBI1 = B.x*I1.y-B.y*I1.x;
			float crossBI2 = B.x*I2.y-B.y*I2.x;
			float crossAI1 = A1.x*I1.y-A1.y*I1.x;
			float crossAI2 = A2.x*I2.y-A2.y*I2.x;
			float crossBA1 = B.x*A1.y-B.y*A1.x;
			float crossBA2 = B.x*A2.y-B.y*A2.x;
			
			crossBA1=crossBA1==0?0.0001:crossBA1;
			crossBA2=crossBA2==0?0.0001:crossBA2;
			
			float t1 = crossAI1/crossBA1;
			float w1 = crossBI1/crossBA1;
			float t2 = crossAI2/crossBA2;
			float w2 = crossBI2/crossBA2;
			
			if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){
				//we do have a collision
				
				Vector normal = rotateVector(B, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside
				normalizePoint(&normal);
				Point collisionPoint=pointMake(((PA1.x+w1*A1.x)+(PA2.x+w2*A2.x))*0.5, ((PA1.y+w1*A1.y)+(PA2.y+w2*A2.y))*0.5);
				float depth = (PA2.x-collisionPoint.x)*normal.x+(PA2.y-collisionPoint.y)*normal.y;
				if(Fabs(depth)>Fabs(pairs[pairCount].depth)){
					pairs[pairCount].depth = depth;
					pairs[pairCount].normal = normal;
					pairs[pairCount].location=collisionPoint;
				}
			}
		}
		if(Fabs(pairs[pairCount].depth)>0){
			pairCount++;
		}
	}
	
	//third case---------------------------------------------------------------------------
	/*
	PA1     PA3
	 \  PB2 /
	  \ /\ /
       X  X
	  / \/ \
	 /  PA2 \
   PB3      PB1
	 
	 V=A /\=B
	 */
	int Bbefore;
	for (Acurrent=0; Acurrent<a->format.polygonInfo.count; Acurrent++) {
		/*Given 3 sequenced vertex, we create two vectors, one from the
		 first to the second vertex and other from the second to the
		 third vertex.*/
		Anext = Acurrent==a->format.polygonInfo.count-1?0:Acurrent+1;
		Abefore = Acurrent==0?a->format.polygonInfo.count-1:Acurrent-1;
		Point PA1 = worldPosition(a->format.polygonInfo.points[Abefore],*a);
		Point PA2 = worldPosition(a->format.polygonInfo.points[Acurrent],*a);
		Point PA3 = worldPosition(a->format.polygonInfo.points[Anext],*a);
		Vector A12 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y);
		Vector A23 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y);
		
		pairs[pairCount].depth = 0;
		pairs[pairCount].normal = pointMake(0, 0);
		for (Bcurrent = 0; Bcurrent<b->format.polygonInfo.count; Bcurrent++) {
			/*for each pair of edge of B, we will find if any of the edges are hitted as shown above*/
			Bnext = Bcurrent==b->format.polygonInfo.count-1?0:Bcurrent+1;
			Bbefore = Bcurrent==0?b->format.polygonInfo.count-1:Bcurrent-1;
			Point PB1 = worldPosition(b->format.polygonInfo.points[Bbefore], *b);
			Point PB2 = worldPosition(b->format.polygonInfo.points[Bcurrent], *b);
			Point PB3 = worldPosition(b->format.polygonInfo.points[Bnext], *b);
			Vector B12 = pointMake(PB2.x-PB1.x, PB2.y-PB1.y);
			Vector B23 = pointMake(PB3.x-PB2.x, PB3.y-PB2.y);
			Vector IA12B23 = pointMake(PB2.x-PA1.x, PB2.y-PA1.y);
			Vector IA23B12 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y);
			
			float crossB12I = B12.x*IA23B12.y-B12.y*IA23B12.x;
			float crossB23I = B23.x*IA12B23.y-B23.y*IA12B23.x;
			float crossA12I = A12.x*IA12B23.y-A12.y*IA12B23.x;
			float crossA23I = A23.x*IA23B12.y-A23.y*IA23B12.x;
			float crossB12A23 = B12.x*A23.y-B12.y*A23.x;
			float crossB23A12 = B23.x*A12.y-B23.y*A12.x;
			
			crossB23A12=crossB23A12==0?0.0001:crossB23A12;
			crossB12A23=crossB12A23==0?0.0001:crossB12A23;
			
			float t1 = crossA12I/crossB23A12;
			float w1 = crossB23I/crossB23A12;
			float t2 = crossA23I/crossB12A23;
			float w2 = crossB12I/crossB12A23;
			
			if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){
				//we do have a collision
				Point collision1 = pointMake((PA1.x+w1*A12.x), (PA1.y+w1*A12.y));
				Point collision2 = pointMake((PA2.x+w2*A23.x), (PA2.y+w2*A23.y));
				Vector c12 = pointMake(collision2.x-collision1.x, collision2.y-collision1.y);
				Vector normal = rotateVector(c12, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside
				normalizePoint(&normal);
				Point collisionPoint=pointMake((collision1.x+collision2.x)*0.5, (collision1.y+collision2.y)*0.5);
				float depth = (PA2.x-PB2.x)*normal.x+(PA2.y-PB2.y)*normal.y;
				depth = -depth;
				pairs[pairCount].depth = depth;
				pairs[pairCount].normal = normal;
				pairs[pairCount].location=collisionPoint;
				pairCount++;
			}
		}
	}
	
	int currentCollision;
	//solves the physics part ot the collision for each collision that has happened

	for (currentCollision =0; currentCollision<pairCount; currentCollision++) {
		State st = physicsResolution(a,b,pairs[currentCollision]);
		state.deltaAngVel += st.deltaAngVel;
		state.deltaPosition=pointMake(st.deltaPosition.x+state.deltaPosition.x, st.deltaPosition.y+state.deltaPosition.y);
		state.deltaVel=pointMake(st.deltaVel.x+state.deltaVel.x, st.deltaVel.y+state.deltaVel.y);
	}
	state.deltaAngVel += a->angularVelocity;
	state.deltaVel = pointMake(a->linearVelocity.x+state.deltaVel.x, a->linearVelocity.y+state.deltaVel.y);
	state.deltaPosition = pointMake(a->position.x+state.deltaPosition.x, a->position.y+state.deltaPosition.y);
	
	return state;
}
Exemplo n.º 15
0
void Mystery::step() {

    if (ended) {
        return;
    }

    AStarSearch<MapSearchNode> astarsearch;

    std::vector<Character *>::iterator itChars;
    for (itChars = characters.begin(); itChars < characters.end(); ++itChars) {

        Character *character = (Character *) *itChars;

        if (character->dead) {
            continue;
        }

        if (character->idle) {

            int targetX = 0;
            int targetY = 0;

            // Any dead people in the same room?

            Character *corpseInRoom = NULL;

            std::vector<Character *>::iterator itOthers;
            for (itOthers = characters.begin(); itOthers < characters.end(); ++itOthers) {
                Character *other = (Character *) *itOthers;
                if (other->currentRoom == character->currentRoom && other->dead) {
                    corpseInRoom = other;
                }
            }

            // Does the character want to chat?
            bool wantsToTalk = rand() % 2 == 0;

            if (corpseFound && (character->murderTarget == NULL || (character->murderTarget != NULL && character->carryingWeapon == NULL))) {

                targetX = victim->position.x;
                targetY = victim->position.y;

                character->currentTarget = NULL;

            } else if (corpseInRoom != NULL && character->murderTarget == NULL) {

                // Go look at the corpse

                targetX = corpseInRoom->position.x;
                targetY = corpseInRoom->position.y;

                character->currentTarget = NULL;

            } else if (character->murderTarget != NULL && !character->murderTarget->dead && character->carryingWeapon != NULL && character->timeBeforeTryMurder == 0) {

                // Murderer goes after its target if he has a weapon and the target is
                // not dead yet

                targetX = character->murderTarget->position.x;
                targetY = character->murderTarget->position.y;

                character->currentTarget = NULL;

            } else if (wantsToTalk) {

                // Goes after another character

                int idxOption = rand() % characters.size();
                Character *option = characters[idxOption];
                targetX = option->position.x;
                targetY = option->position.y;

                character->currentTarget = NULL;

            } else {

                // Looks for a POI matching the characters interest in any room

                Room *room;
                std::vector<POI *> points;

                bool notSearchedOnly = false;

                Interest interest = character->interest;
                if (character->murderTarget != NULL && ((character->carryingWeapon == NULL && character->timeBeforeSearchWeapon == 0 && !character->murderTarget->dead) || (character->carryingWeapon != NULL && character->murderTarget->dead))) {

                    // If the character is a murderer and is looking for a weapon, or
                    // if he/she already killed the target, he/she goes to a container
                    // to grab/hide the weapon

                    if (character->carryingWeapon != NULL) {
                        interest = InterestContainerConceiled;
                    } else {
                        interest = InterestContainerVisible;
                    }

                    // If he has no weapon, searches only the containers not
                    // searched yet

                    notSearchedOnly = character->carryingWeapon == NULL;

                } else {

                    // There's a chance the character wants to see a container
                    int chance = rand() % 100;

                    if (chance < 25) {
                        interest = InterestContainerVisible;
                    } else if (chance < 50) {
                        interest = InterestContainerConceiled;
                    }
                }

                do {
                    int roomIdx = rand() % rooms.size();
                    room = rooms[roomIdx];

                    points = room->getPointsOfInterest(interest, notSearchedOnly);

                } while (points.size() == 0);

                // Goes after an interesting random POI

                int idx = rand() % points.size();
                POI *poi = points[idx];

                character->currentTarget = poi;

                targetX = poi->position.x;
                targetY = poi->position.y;
            }

            character->idle = false;

            MapSearchNode nodeStart;
            nodeStart.x = (int) character->position.x;
            nodeStart.y = (int) character->position.y;
            nodeStart.mystery = this;

            MapSearchNode nodeEnd;
            nodeEnd.x = targetX;
            nodeEnd.y = targetY;
            nodeEnd.mystery = this;

            astarsearch.SetStartAndGoalStates(nodeStart, nodeEnd);

            unsigned int SearchState;

            do {

                SearchState = astarsearch.SearchStep();

            } while( SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_SEARCHING );

            // Found a path to the target

            if (SearchState == AStarSearch<MapSearchNode>::SEARCH_STATE_SUCCEEDED) {

                MapSearchNode *node = astarsearch.GetSolutionStart();

                while (node) {

                    // Builds the steps for the character to reach its target

                    Step *step = new Step();
                    step->position = pointMake(node->x, node->y);
                    step->conversationWith = NULL;
                    step->type = StepTypeWalk;
                    step->duration = STEP_DURATION;

                    if (character->currentTarget != NULL && pointEqualsIntegral(step->position, character->currentTarget->position)) {

                        Step *step = new Step();
                        step->position = pointMake(node->x, node->y);
                        step->conversationWith = NULL;
                        step->type = StepTypeStartInteractPOI;
                        step->duration = 1;

                        character->addStep(step);

                        step = new Step();
                        step->position = pointMake(node->x, node->y);
                        step->conversationWith = NULL;
                        step->type = StepTypeInteractPOI;
                        step->duration = rand() % MAX_DURATION_POI_INTERACTION + MIN_DURATION_POI_INTERACTION;

                        character->addStep(step);

                        step = new Step();
                        step->position = pointMake(node->x, node->y);
                        step->conversationWith = NULL;
                        step->type = StepTypeEndInteractPOI;
                        step->duration = 1;

                        character->addStep(step);

                    } else {

                        Step *step = new Step();
                        step->position = pointMake(node->x, node->y);
                        step->conversationWith = NULL;
                        step->type = StepTypeWalk;
                        step->duration = STEP_DURATION;

                        character->addStep(step);
                    }

                    node = astarsearch.GetSolutionNext();
                }

                astarsearch.FreeSolutionNodes();
            }

        } else {

            // Updates the character's path by 1 unit of time

            character->updatePath();

            if (!character->isHavingConversation() && character->conversationInterval > 0) {
                character->conversationInterval--;
            }

            if (character->timeBeforeSearchWeapon > 0) {
                character->timeBeforeSearchWeapon--;
            } else {

                if (character->timeBeforeTryMurder > 0 && character->carryingWeapon != NULL) {
                    character->timeBeforeTryMurder--;
                }
            }

            Room *currentRoom = NULL;

            // Determines if the character entered or left a room

            std::vector<Room *>::iterator itRooms;
            for (itRooms = rooms.begin(); itRooms < rooms.end(); ++itRooms) {
                Room *room = (Room *) *itRooms;

                if (rectContainsPoint(room->bounds, character->position)) {
                    currentRoom = room;
                }
            }

            if (currentRoom != character->currentRoom) {

                if (character->currentRoom != NULL) {
                    printf("%s left %s\n", character->name.c_str(), character->currentRoom->name.c_str());
                    registerEventForAllInRoom(EventLeftRoom, character, NULL, character->currentRoom, NULL, NULL);
                }

                character->currentRoom = currentRoom;

                if (character->currentRoom != NULL) {
                    printf("%s entered %s\n", character->name.c_str(), character->currentRoom->name.c_str());
                    registerEventForAllInRoom(EventEnteredRoom, character, NULL, character->currentRoom, NULL, NULL);

                    if (character != murderer) {
                        // Register any weapons saw before but missing
                        std::vector<Memory *>::iterator it;
                        std::vector<Memory *> memories = character->getMemories();
                        std::vector<Memory *> considered;

                        for (it = memories.begin(); it < memories.end(); ++it) {

                            Memory *memory = (Memory *) *it;

                            if (memory->event == EventSawWeapon && memory->where == character->currentRoom && memory->when < time && !pointEqualsIntegral(memory->whatInside->position, memory->what->visualPosition)) {

                                std::vector<Memory *>::iterator itOther;

                                bool found = false;

                                for (itOther = considered.begin(); itOther < considered.end(); ++itOther) {

                                    Memory *other = (Memory *) *itOther;

                                    if (other->where == memory->where && other->whatInside == memory->whatInside) {
                                        found = true;
                                        break;
                                    }
                                }

                                if (!found) {
                                    registerEventFor(character, EventWeaponMissing, NULL, NULL, character->currentRoom, memory->what, memory->whatInside);
                                    considered.push_back(memory);
                                }
                            }
                        }
                    }

                    // Register visible weapons the character sees in the room
                    std::vector<POI *>::iterator itPOI;
                    for (itPOI = character->currentRoom->pointsOfInterest.begin(); itPOI < character->currentRoom->pointsOfInterest.end(); ++itPOI) {

                        POI *poi = (POI *) *itPOI;

                        if (poi->interest == InterestContainerVisible && poi->contents != NULL && poi->contents->isWeapon()) {
                            registerEventFor(character, EventSawWeapon, NULL, NULL, character->currentRoom, poi, poi->contents);
                        }
                    }

                    std::vector<Character *>::iterator itOthers;
                    for (itOthers = characters.begin(); itOthers < characters.end(); ++itOthers) {
                        Character *other = (Character *) *itOthers;

                        if (other != character && other->currentRoom == character->currentRoom) {

                            registerEventFor(character, EventWasInRoom, other, NULL, character->currentRoom, NULL, NULL);

                            // Register others having conversations
                            if (other->isHavingConversation()) {
                                Character *another = other->getCurrentStep()->conversationWith;
                                registerEventFor(character, EventWasHavingConversation, other, another, character->currentRoom, NULL, NULL);
                            }

                            // Register others interacting with POIs
                            if (other->isInteractingWithPOI()) {
                                registerEventFor(character, EventWasInteractingPOI, other, NULL, character->currentRoom, other->currentTarget, NULL);
                            }
                        }
                    }
                }
            }

            if (character->getCurrentStep() != NULL) {

                Character *another;

                switch (character->getCurrentStep()->type) {
                case StepTypeStartInteractPOI:
                    registerEventForAllInRoom(EventStartInteractPOI, character, NULL, character->currentRoom, character->currentTarget, NULL);
                    break;
                case StepTypeEndInteractPOI:
                    another = character->getCurrentStep()->conversationWith;
                    registerEventForAllInRoom(EventEndInteractPOI, character, another, character->currentRoom, character->currentTarget, NULL);
                    break;
                case StepTypeEndConversation:
                    another = character->getCurrentStep()->conversationWith;
                    registerEventForAllInRoom(EventEndConversation, character, another, character->currentRoom, NULL, NULL);
                    break;
                default:
                    break;
                }
            }

            bool aloneInRoom = true;
            bool aloneInRoomWithVictim = true;
            bool allNearCorpse = pointEqualsIntegral(character->position, victim->position);

            std::vector<Character *>::iterator itOthers;
            for (itOthers = characters.begin(); itOthers < characters.end(); ++itOthers) {
                Character *other = (Character *) *itOthers;

                allNearCorpse = allNearCorpse && pointEqualsIntegral(other->position, victim->position);

                if (other != character) {
                    if (character->currentRoom == other->currentRoom) {
                        aloneInRoom = false;

                        if (other != character->murderTarget) {
                            aloneInRoomWithVictim = false;
                        }
                    }

                    if (victim->dead && other == victim && pointEqualsIntegral(character->position, other->position) && !corpseFound) {

                        printf("*** %s found %s's body in the %s ***\n", character->name.c_str(), victim->name.c_str(), character->currentRoom->name.c_str());
                        corpseFound = true;
                        corpseFoundTime = time;
                        corpseFoundRoom = character->currentRoom;
                        character->clearPath();

                        std::vector<Character *>::iterator itAll;
                        for (itAll = characters.begin(); itAll < characters.end(); ++itAll) {
                            registerEventFor(*itAll, EventFoundBody, character, NULL, corpseFoundRoom, NULL, NULL);
                        }
                    }

                    // Looks for:
                    // - adjacent characters
                    // - one of them without a POI in mind
                    // - both not already in a conversation
                    // - both conversation intervals expired

                    if (pointAdjacentIntegral(character->position, other->position) &&
                            (character->currentTarget == NULL || other->currentTarget == NULL) &&
                            (!character->isHavingConversation() && !other->isHavingConversation()) &&
                            (character->conversationInterval == 0 && other->conversationInterval == 0) && !corpseFound) {

                        int duration = rand() % MAX_DURATION_CONVERSATION + MIN_DURATION_CONVERSATION;

                        // If both characters have matching interests, the talk is longer

                        if (character->interest == other->interest) {
                            duration *= CONVERSATION_INTEREST_FACTOR;
                        }

                        character->clearPath();
                        other->clearPath();

                        Step *step = new Step();
                        step->position = character->position;
                        step->duration = duration;
                        step->conversationWith = other;
                        step->type = StepTypeConversation;
                        character->addStep(step);

                        step = new Step();
                        step->position = character->position;
                        step->duration = 1;
                        step->conversationWith = other;
                        step->type = StepTypeEndConversation;
                        character->addStep(step);

                        step = new Step();
                        step->position = other->position;
                        step->duration = duration;
                        step->conversationWith = character;
                        step->type = StepTypeConversation;
                        other->addStep(step);

                        step = new Step();
                        step->position = other->position;
                        step->duration = 1;
                        step->conversationWith = character;
                        step->type = StepTypeEndConversation;
                        other->addStep(step);

                        character->conversationInterval = CONVERSATION_INTERVAL;
                        other->conversationInterval = CONVERSATION_INTERVAL;

                        registerEventForAllInRoom(EventStartConversation, character, other, character->currentRoom, NULL, NULL);
                        registerEventForAllInRoom(EventStartConversation, other, character, character->currentRoom, NULL, NULL);

                        printf("%s and %s are having a conversation\n", character->name.c_str(), other->name.c_str());

                    }
                }
            }

            if (allNearCorpse && corpseFound) {
                ended = true;
                printf("*** Mystery finished ***\n");
            }

            // Murderer-specific actions

            if (character->murderTarget != NULL) {

                // Grabs a weapon if:
                // - interval elapsed
                // - not carrying a weapon already
                // - murder target is not dead
                // - has a target POI
                // - reached the target POI
                // - POI has contents
                // - POI's content is a weapon matching interest
                // - alone in the room

                if (character->timeBeforeSearchWeapon == 0 &&
                        character->carryingWeapon == NULL &&
                        !victim->dead &&
                        character->currentTarget != NULL &&
                        pointEqualsIntegral(character->position, character->currentTarget->position) &&
                        character->currentTarget->contents != NULL &&
                        character->currentTarget->contents->interest == character->weaponInterest &&
                        aloneInRoom) {

                    character->carryingWeapon = character->currentTarget->contents;
                    character->carryingWeapon->position = pointMake(-20, -20);
                    character->currentTarget->contents = NULL;

                    printf("*** %s got a %s! ***\n", character->name.c_str(), character->carryingWeapon->description.c_str());
                }

                // Kills the victim if:
                // - interval elapsed
                // - already got a weapon
                // - near the victim
                // - murder target is not dead
                // - alone in the room with victim

                if (character->timeBeforeTryMurder == 0 &&
                        character->carryingWeapon != NULL &&
                        pointAdjacentIntegral(character->position, victim->position) &&
                        !victim->dead &&
                        aloneInRoomWithVictim) {

                    printf("*** %s murdered %s! ***\n", character->name.c_str(), victim->name.c_str());
                    victim->dead = true;
                    crimeWeapon = character->carryingWeapon;

                    character->clearPath();

                    // Murderer will lie

                    int idx = rand() % character->currentRoom->pointsOfInterest.size();
                    POI *poi = character->currentRoom->pointsOfInterest[idx];

                    registerEventFor(character, EventStartInteractPOI, character, NULL, character->currentRoom, poi, NULL);
                    registerEventFor(character, EventEndInteractPOI, character, NULL, character->currentRoom, poi, NULL);
                }

                // Hides the weapon if:
                // - carrying a weapon
                // - murder target is dead
                // - has a target POI
                // - reached the target POI
                // - POI has no contents
                // - alone in the room

                if (character->carryingWeapon != NULL &&
                        victim->dead &&
                        character->currentTarget != NULL &&
                        pointEqualsIntegral(character->position, character->currentTarget->position) &&
                        character->currentTarget->contents == NULL &&
                        aloneInRoom) {

                    character->carryingWeapon->position = character->currentTarget->visualPosition;

                    if (character->currentTarget->interest == InterestContainerConceiled) {
                        character->carryingWeapon->position = pointMake(-20, -20);
                    }

                    character->currentTarget->contents = character->carryingWeapon;
                    character->carryingWeapon = NULL;

                    printf("*** %s hid the %s in the %s, in the %s! ***\n", character->name.c_str(), character->currentTarget->contents->description.c_str(), character->currentTarget->description.c_str(), currentRoom->name.c_str());
                }
            }
        }
    }

    astarsearch.EnsureMemoryFreed();

    time++;
}
Exemplo n.º 16
0
void InvestigationScene::questionStart() {
    
    inputLocked = true;
        
    currentFilter.where = NULL;
    currentFilter.who = NULL;
    
    actionButton->setEnabled(false);
    actionButton->setVisible(false);
    
    cancelQuestionButton->setEnabled(true);
    cancelQuestionButton->setVisible(true);
    
    removeQuestionElements();
    
    std::string question = "Select a question to ask ";
    question.append(activeCharacter->name);
    
    questionLabel->setText(question.c_str());
    questionLabel->setVisible(true);
    
    bkgQuestion->setVisible(true);
    
    Button *button = new Button("Who was in the...", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(400, 200));
    button->setTag(101);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
    
    button = new Button("Where was...", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(400, 260));
    button->setTag(102);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
    
    button = new Button("Anything strange...", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(400, 320));
    button->setTag(103);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
    
    button = new Button("You are the murderer!", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(400, 380));
    button->setTag(104);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
}
Exemplo n.º 17
0
void InvestigationScene::setupScene() {
    
    std::vector<Point> positions;
    positions.push_back(pointMake(32, 48));
    positions.push_back(pointMake(34, 48));
    positions.push_back(pointMake(36, 48));
    positions.push_back(pointMake(38, 48));
    positions.push_back(pointMake(40, 49));
    positions.push_back(pointMake(40, 51));
    positions.push_back(pointMake(40, 53));
    positions.push_back(pointMake(30, 49));
    positions.push_back(pointMake(30, 51));
    positions.push_back(pointMake(32, 52));
    
    const char *fontFile = "res/AveriaSerif-Regular.ttf";
    
    font = al_load_font(fontFile, 18, 0);
    if (!font) {
        Director::getInstance()->abortWithMessage("%s not found or failed to load\n", fontFile);
    }
    
    fontBig = al_load_font(fontFile, 26, 0);
    if (!fontBig) {
        Director::getInstance()->abortWithMessage("%s not found or failed to load\n", fontFile);
    }
    
    searchSound = al_load_sample("res/search.wav");
    if (!searchSound) {
        Director::getInstance()->abortWithMessage("%s not found or failed to load\n", "res/search.wav");
    }
    
    clickSound = al_load_sample("res/click.wav");
    if (!clickSound) {
        Director::getInstance()->abortWithMessage("%s not found or failed to load\n", "res/click.wav");
    }
    
    std::vector<TilemapLayer *> layers = TilemapLayer::parseTMXFile("res/mansion.tmx");
    std::vector<TilemapLayer *>::iterator it;
    
    TilemapLayer *firstLayer = layers[0];
    
    camera = new Camera(800, 600, firstLayer->getBoundsSize().width, firstLayer->getBoundsSize().height);
    
    for (it = layers.begin(); it < layers.end(); ++it) {
        
        TilemapLayer *layer = (TilemapLayer *) *it;
        layer->setCamera(camera);
        addToDisplayList(layer);
        
        if (layer->isCollision()) {
            collision = layer;
        }
    }
            
    playerSprite = new Spritesheet("res/professor_walk_cycle_no_hat.png", 64, 64);
    playerSprite->setTag(PLAYER_SPRITE_TAG);
    playerSprite->setCamera(camera);
    playerSprite->setPosition(pointMake(35 * 32, 50 * 32));
    playerSprite->setAnchorPoint(pointMake(0.5, 0.9));
    playerSprite->setAutoZOrder(true);
    addToDisplayList(playerSprite);
    
    mysterySeed = 0;
    
    do {
        
        mysteryTime = 0;
        mysterySeed = time(0);
        
        mystery = new Mystery("res/mansion.xml", mysterySeed, collision->getData(), collision->getSize().width, collision->getSize().height);
        
        while (!mystery->ended && mysteryTime < MAX_MYSTERY_DURATION) {
            mystery->step();
            mysteryTime++;
        }
        
        if (!mystery->ended) {
            delete mystery;
            mystery = NULL;
        }
        
    } while (mystery == NULL);
                    
    printf("Case seed: %d Total duration: %ld %s\n", mysterySeed, mysteryTime, timeToString(mysteryTime, true).c_str());
    
    std::vector<Character *> characters = mystery->getCharacters();
    std::vector<Character *>::iterator itChars;
    
    int i = 0;
    
    for (itChars = characters.begin(); itChars < characters.end(); ++itChars) {
        
        Character *character = (Character *) *itChars;
        
        int frame = i * 2;
        
        if (!character->dead) {
            int idx = rand() % positions.size();
            Point pos = positions[idx];
            
            character->position = pos;
            
            positions.erase(positions.begin() + idx);
        } else {
            frame++;
        }
        
        Spritesheet *sprite = new Spritesheet("res/characters.png", 64, 64);
        sprite->setTag(character->tag);
        sprite->setCamera(camera);
        sprite->setAnchorPoint(pointMake(0.5, 0.9));
        sprite->setAutoZOrder(true);
        sprite->setFrame(frame);
        
        Rect tileRect = collision->getTileRect(character->position.x, character->position.y);
        sprite->setPosition(rectMidPoint(tileRect));
        
        addToDisplayList(sprite);        
        
        i++;
    }
    
    std::vector<POI *>::iterator itWeapons;
    
    i = 0;
    
    for (itWeapons = mystery->weapons.begin(); itWeapons < mystery->weapons.end(); ++itWeapons) {
        
        POI *weapon = (POI *) *itWeapons;
        
        Spritesheet *sprite = new Spritesheet("res/weapons.png", 32, 32);
        sprite->setTag(i + 20);
        sprite->setFrame(i);
        sprite->setCamera(camera);
        sprite->setAnchorPoint(pointMake(0.5, 0.5));
        sprite->setZOrder(400);
        
        Rect tileRect = collision->getTileRect(weapon->position.x, weapon->position.y);
        sprite->setPosition(rectMidPoint(tileRect));
        
        addToDisplayList(sprite);
        
        i++;
    }
    
    actionButton = new Button("action", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
    actionButton->setZOrder(500);
    actionButton->setAnchorPoint(pointMake(0.5, 1));
    actionButton->setPosition(pointMake(400, 400));
    actionButton->setCamera(camera);
    actionButton->setHandler(this);
    
    addToDisplayList(actionButton);
    
    Spritesheet *bkgRoomLabel = new Spritesheet("res/bkg_room_name.png");
    bkgRoomLabel->setAnchorPoint(pointMake(0.5, 0.5));
    bkgRoomLabel->setPosition(pointMake(400, 40));
    bkgRoomLabel->setZOrder(501);
    
    addToDisplayList(bkgRoomLabel);
    
    currentRoomLabel = new Label("room", font, al_map_rgb(0, 0, 0));
    currentRoomLabel->setAnchorPoint(pointMake(0.5, 0.5));
    currentRoomLabel->setPosition(bkgRoomLabel->getPosition());
    currentRoomLabel->setZOrder(502);
    
    addToDisplayList(currentRoomLabel);
    
    Spritesheet *bkgWeaponLabel = new Spritesheet("res/bkg_room_name.png");
    bkgWeaponLabel->setAnchorPoint(pointMake(0.5, 0.5));
    bkgWeaponLabel->setPosition(pointMake(720, 40));
    bkgWeaponLabel->setZOrder(501);
    
    addToDisplayList(bkgWeaponLabel);
    
    crimeWeaponLabel = new Label("No weapon", font, al_map_rgb(0, 0, 0));
    crimeWeaponLabel->setAnchorPoint(pointMake(0.5, 0.5));
    crimeWeaponLabel->setPosition(bkgWeaponLabel->getPosition());
    crimeWeaponLabel->setZOrder(502);
    
    addToDisplayList(crimeWeaponLabel);
    
    Spritesheet *bkgAccusationLabel = new Spritesheet("res/bkg_room_name.png");
    bkgAccusationLabel->setAnchorPoint(pointMake(0.5, 0.5));
    bkgAccusationLabel->setPosition(pointMake(80, 40));
    bkgAccusationLabel->setZOrder(501);
    
    addToDisplayList(bkgAccusationLabel);
    
    char buf[100];
    sprintf(buf, "%d accusations left", MAX_ACCUSATIONS);
    
    accusationsLabel = new Label(buf, font, al_map_rgb(0, 0, 0), 120);
    accusationsLabel->setAnchorPoint(pointMake(0.5, 0.5));
    accusationsLabel->setPosition(bkgAccusationLabel->getPosition());
    accusationsLabel->setZOrder(502);
    
    addToDisplayList(accusationsLabel);
    
    bkgQuestion = new Spritesheet("res/bkg_question.png");
    bkgQuestion->setAnchorPoint(pointMake(0.5, 0.5));
    bkgQuestion->setPosition(pointMake(400, 300));
    bkgQuestion->setZOrder(503);
    bkgQuestion->setVisible(false);
        
    addToDisplayList(bkgQuestion);
    
    questionLabel = new Label("question", font, al_map_rgb(0, 0, 0), 350);
    questionLabel->setAnchorPoint(pointMake(0.5, 0.5));
    questionLabel->setPosition(pointMake(400, 120));
    questionLabel->setZOrder(504);
    questionLabel->setVisible(false);
    
    addToDisplayList(questionLabel);
    
    whenLabel = new Label("00:00 and 00:15", fontBig, al_map_rgb(0, 0, 0));
    whenLabel->setAnchorPoint(pointMake(0.5, 0.5));
    whenLabel->setPosition(pointMake(400, 300));
    whenLabel->setZOrder(504);
    whenLabel->setVisible(false);
    
    addToDisplayList(whenLabel);
    
    askQuestionButton = new Button("Ask", font, BTN_TXT_COLOR, "res/btn_med.png", "res/btn_med_pressed.png");
    askQuestionButton->setZOrder(504);
    askQuestionButton->setAnchorPoint(pointMake(0.5, 0.5));
    askQuestionButton->setPosition(pointMake(480, 490));
    askQuestionButton->setHandler(this);
    askQuestionButton->setVisible(false);
    askQuestionButton->setEnabled(false);
    
    addToDisplayList(askQuestionButton);
    
    cancelQuestionButton = new Button("Cancel", font, BTN_TXT_COLOR, "res/btn_med.png", "res/btn_med_pressed.png");
    cancelQuestionButton->setZOrder(504);
    cancelQuestionButton->setAnchorPoint(pointMake(0.5, 0.5));
    cancelQuestionButton->setPosition(pointMake(300, 490));
    cancelQuestionButton->setHandler(this);
    cancelQuestionButton->setVisible(false);
    cancelQuestionButton->setEnabled(false);
    
    addToDisplayList(cancelQuestionButton);
    
    bkgSpeech = new Spritesheet("res/speech.png");
    bkgSpeech->setAnchorPoint(pointMake(0.35, 1));
    bkgSpeech->setCamera(camera);
    bkgSpeech->setZOrder(503);
    bkgSpeech->setVisible(false);
    
    addToDisplayList(bkgSpeech);
    
    speechLabel = new Label("speech", font, al_map_rgb(0, 0, 0), 280);
    speechLabel->setAnchorPoint(pointMake(0.5, 0.5));
    speechLabel->setCamera(camera);
    speechLabel->setZOrder(504);
    speechLabel->setVisible(false);
    
    addToDisplayList(speechLabel);
    
    speechCountLabel = new Label("1/1", font, al_map_rgb(0, 0, 0));
    speechCountLabel->setAnchorPoint(pointMake(1, 0.5));
    speechCountLabel->setCamera(camera);
    speechCountLabel->setZOrder(504);
    speechCountLabel->setVisible(false);
    
    addToDisplayList(speechCountLabel);
    
    speechButton = new Button(bkgSpeech->getFrameSize());
    speechButton->setAnchorPoint(bkgSpeech->getAnchorPoint());
    speechButton->setCamera(camera);
    speechButton->setZOrder(504);
    speechButton->setEnabled(false);
    speechButton->setHandler(this);
    
    addToDisplayList(speechButton);
    
    camera->setCenter(playerSprite->getPosition());
    
    activeCharacter = NULL;
    activePOI = NULL;
    currentRoom = NULL;
    crimeWeapon = NULL;
    
    accusationsLeft = MAX_ACCUSATIONS;
    questionsAsked = 0;
    
    moving = pointMake(0, 0);
    moveDir = 0;
    curFrame = 0;
    
    endScene = false;
    debug = false;
    
    currentFilter.timeStart = 0;
    currentFilter.timeEnd = QUESTION_INTERVAL;
    
    std::string msg;
    msg.append(mystery->victim->name);
    msg.append("'s body was found around ");
    msg.append(timeToString(mystery->corpseFoundTime + START_TIME, false));
    msg.append(" in the ");
    msg.append(mystery->corpseFoundRoom->name);
    msg.append(".");
    
    ModalDialog *dialog = new ModalDialog(msg.c_str(), font, "OK", NULL);
    dialog->setHandler(this);
    dialog->showInScene(this, 1000);
    
    music = al_load_audio_stream("res/mystery.ogg", 4, 2048);
    al_set_audio_stream_playmode(music, ALLEGRO_PLAYMODE_LOOP);
    al_attach_audio_stream_to_mixer(music, al_get_default_mixer());
    
    inDialogue = false;
    inputLocked = true;
    
    investigationStartTime = time(0);
}
Exemplo n.º 18
0
int main(){

    //EPIPHANY VARIABLES
	e_platform_t platform;
	e_epiphany_t dev;

	//DEBUG VARIABLES
	unsigned read_buffer[RAM_SIZE/4];
	unsigned read_data;
	unsigned addr;
	int i,j,k;

	char filename[9] = "logs.txt";
	FILE* file = fopen(filename,"w");

	//TIME VARIABLEs
	struct timeval initTime, endTime;
	long int timediff;

    //initialize the cores
	e_init(NULL);
	e_get_platform_info(&platform);

	clearMemory();

	e_open(&dev, 0,0,4,4);

	e_reset_group(&dev);
	//initialize physics objects and Physics Engine
	PhysicsEngine engine;
	engine.count = 0;

	PhysicsObject obj;
    obj.type = OBJECT_TYPE_POLYGON;
	addPointToObject(&obj,pointMake(0,0));
	addPointToObject(&obj,pointMake(2,-2));
	addPointToObject(&obj,pointMake(4,0));
	addPointToObject(&obj,pointMake(2,2));

	obj.rotationCenter = pointMake(2,0);
	obj.position = pointMake(0.5,0.99);
	obj.rotation = 0;
	obj.inverseInertia = 1;
	obj.inverseMass = 1;
	obj.linearVelocity = pointMake(0,-1);
	obj.angularVelocity = 0;

	addObject(&engine,obj);

	//-------
	PhysicsObject obj2;
    obj2.type = OBJECT_TYPE_POLYGON;
	addPointToObject(&obj2,pointMake(0,-1));
	addPointToObject(&obj2,pointMake(2,-4));
	addPointToObject(&obj2,pointMake(4,-1));

	obj2.rotationCenter = pointMake(2,-2);
	obj2.position = pointMake(0,0);
	obj2.rotation = 0;
	obj2.inverseInertia = 1;
	obj2.inverseMass = 1;
	obj2.linearVelocity = pointMake(0,0);
	obj2.angularVelocity = 0;

	addObject(&engine,obj2);

	//calculate minimun circles
	minimunCircles(&engine);

    printf("%x\n",sizeof(PhysicsObject));

    distributeObjectsToCores(&engine,&dev);

    printf("frame->%x\n",sizeof(Frame));
    char start = 1;
    for(i=0;i<4;i++){
        for(j=0;j<4;j++){
            e_load("epiphanyProgram.srec",&dev,i,j,E_TRUE);
            e_write(&dev,i,j,COMMADDRESS_READY, &start,sizeof(char));
            //usleep(20000);
        }
    }

    //usleep(3000000);
    long long int TotalTime;
    gettimeofday(&initTime,NULL);

    Frame frm1, frm2;
    while(1){
        e_read(&dev,0,0,COMMADDRESS_FRAMES,&frm1,sizeof(Frame));
        e_read(&dev,0,1,COMMADDRESS_FRAMES,&frm2,sizeof(Frame));

        printf("Frame---%d\nvelocity(%g,%g)\nposition(%g,%g)\nangVel%g\n",frm1.frameNumber,frm1.velocity.x,frm1.velocity.y,frm1.position.x,frm1.position.y,frm1.angVelocity);
        printf("Frame---%d\nvelocity(%g,%g)\nposition(%g,%g)\nangVel%g\n",frm1.frameNumber,frm2.velocity.x,frm2.velocity.y,frm2.position.x,frm2.position.y,frm2.angVelocity);
        gettimeofday(&endTime, NULL);
        TotalTime =endTime.tv_sec*1000+endTime.tv_usec/1000-initTime.tv_usec/1000-initTime.tv_sec*1000;
        float fps= frm1.frameNumber;
        fps = fps*1000/(float)TotalTime;
        printf("FPS=%g\n",fps);
        if(frm1.frameNumber >=20  && frm2.frameNumber >= 20){
            break;
        }
    }

    gettimeofday(&endTime, NULL);
    TotalTime =endTime.tv_sec*1000+endTime.tv_usec/1000-initTime.tv_usec/1000-initTime.tv_sec*1000;
    printf("TotalTime = %lld\n", TotalTime);

    //-------------------------DUMP MEMORY -----------------------------
	//read all memory
	e_open(&dev, 0, 0, platform.rows, platform.cols);
	fprintf(file,"(ROW,COL)   ADDRESS   DATA\n");
	fprintf(file,"-----------------------------\n");
	for (i=0; i<(platform.rows); i++) {
		for (j=0; j<(platform.cols); j++) {
			for(k=0;k<RAM_SIZE/4;k++){
				addr=4*k;
				e_read(&dev, i, j, addr, &read_data, sizeof(int));
				read_buffer[k]=read_data;
			}
			for(k=0;k<RAM_SIZE/4;k++){
				fprintf(file,"(%2d,%2d)     0x%08x   0x%08x\n",i,j,k*4,read_buffer[k]);
			}
		}
	}

	fclose(file);
	e_close(&dev);
	e_finalize();

	return EXIT_SUCCESS;

}
Exemplo n.º 19
0
void InvestigationScene::dialogueStart() {
    
    inDialogue = true;
    
    questionsAsked++;
    
    speechLines.clear();
    
    std::vector<std::string> memories = activeCharacter->getFormattedMemories(currentFilter);
    
    if (memories.size() > 0) {
        
        speechLines.insert(speechLines.end(), memories.begin(), memories.end());
        
    } else {
        
        if (currentFilter.who == NULL) {
            
            if (currentFilter.strange) {
                speechLines.push_back(std::string("I don't remember anything strange happening there around that time."));
            } else {
                speechLines.push_back(std::string("I don't remember seeing anyone there around that time."));
            }
            
        } else if (currentFilter.where == NULL) {
            
            std::string res = "I don't remember seeing ";
            
            if (currentFilter.who->male) {
                res.append("him ");
            } else {
                res.append("her ");
            }
            
            res.append("around that time.");
            
            speechLines.push_back(res);
        }
    }
    
    speechIdx = 0;
    
    Drawable *sprite = getByTag(activeCharacter->tag);
    
    bkgSpeech->setVisible(true);
    bkgSpeech->setPosition(pointMake(sprite->getPosition().x, sprite->getPosition().y - 20));
    
    speechLabel->setText(speechLines[speechIdx].c_str());
    speechLabel->setVisible(true);
    speechLabel->setPosition(pointOffset(bkgSpeech->getPosition(), 54, -175));
    
    char buff[10];
    sprintf(buff, "%d/%lu", speechIdx + 1, speechLines.size());
    speechCountLabel->setText(buff);
    speechCountLabel->setVisible(true);
    speechCountLabel->setPosition(pointOffset(bkgSpeech->getPosition(), 188, -68));
    
    speechButton->setEnabled(true);
    speechButton->setPosition(bkgSpeech->getPosition());
    
    speechIdx++;
}