Beispiel #1
0
/**
 * @function GUI_ObjSetFocused
 * @brief set the flag <Focused> of a generic object
 * @param const g_obj_st *obj: generic object
 * @param bool p: new flag value
 * @return none
 */
void GUI_ObjSetFocused(g_obj_st /*@null@*/ *obj, bool p) {

  g_obj_st *ptr;

  if(obj == NULL) obj = lastAddedObj;
  if(obj != NULL) {

    /*if focus == true, we shall check that the given object can receive focus */
    if(p == true)  {
      if(GUI_ObjIsFocusable(obj) && GUI_ObjIsDisabled(obj) == false && GUI_ObjIsFocused(obj) == false) {

        /*find & clear previously focused object*/
        ptr = GetObjectList();

        while(ptr != NULL) {
          if(GUI_ObjIsFocused(ptr)) {
            StateSet(ptr, OBJ_S_FOCUSED, false);
            GUI_ObjSetNeedRefresh(ptr, true);
          }
          ptr = ptr->next;
        }

        /*give focus to object*/
        StateSet(obj, OBJ_S_FOCUSED, true);
        GUI_ObjSetNeedRefresh(obj, true);
      }
    }
    else {
      if(GUI_ObjIsFocused(obj)) {
        StateSet(obj, OBJ_S_FOCUSED, false);
        GUI_ObjSetNeedRefresh(obj, true);
      }
    }
  }
}
Beispiel #2
0
/**
 * @function GUI_GroupRefresh
 * @brief force refresh o group of object
 * @param group_t g: selected group
 * @param bool p
 * @return none
 */
void GUI_GroupRefresh(group_t g, bool p) {
  g_obj_st *ptr = GetObjectList();
  while(ptr != NULL) {
    if(ptr->group == g) GUI_ObjSetNeedRefresh(ptr, p);
    ptr = ptr->next;
  }
}
Beispiel #3
0
/**
 * @function GUI_GroupNotify
 * @brief notify or not a group of object
 * @param group_t g: selected group
 * @param bool p: notified / not notified
 * @return none
 */
void GUI_GroupNotify(group_t g, bool p) {
  g_obj_st *ptr = GetObjectList();
  while(ptr != NULL) {
    if(ptr->group == g) GUI_ObjSetNotified(ptr, p);
    ptr = ptr->next;
  }
}
Beispiel #4
0
bool Model::ImportUVCoords (Model* other, IProgressCtl &progctl)
{
	vector <MdlObject*> objects=GetObjectList ();
	MdlObject *srcobj = other->root;

	vector <Vector3> pverts;

	int numPl = 0, curPl=0;
	for (int a=0;a<objects.size();a++)
		numPl += objects[a]->poly.size();
	
	for (int a=0;a<objects.size();a++) {
		MdlObject *obj = objects[a];
		Matrix objTransform;
		obj->GetFullTransform(objTransform);

		// give each polygon an independent set of vertices, this will be optimized back to normal later
		vector <Vertex> nverts;
		for (int b=0;b<obj->poly.size();b++) {
			Poly *pl = obj->poly[b];
			for (int v=0;v<pl->verts.size();v++) {
				nverts.push_back (obj->verts[pl->verts[v]]);
				pl->verts[v]=nverts.size()-1;
			}
		}
		obj->verts=nverts;

		// match our polygons with the ones of the other model
		for (int b=0;b<obj->poly.size();b++) {
			Poly *pl = obj->poly[b];

			pverts.clear();
			for (int pv=0;pv<pl->verts.size();pv++) {
				Vector3 tpos;
				objTransform.apply (&obj->verts [pl->verts[pv]].pos, &tpos);
				pverts.push_back (tpos);
			}

			int startVertex;
			int bestpl = MatchPolygon (srcobj,pverts,startVertex);
			if (bestpl >= 0) {
				// copy texture coordinates from rt->poly[bestpl] to pl
				Poly *src = srcobj->poly [bestpl];
				for (int v=0;v<src->verts.size();v++) {
					Vertex &dstvrt = obj->verts[pl->verts[(v + startVertex)%pl->verts.size()]];
					dstvrt.tc[0] = srcobj->verts[src->verts[v]].tc[0];
				}
			}

			progctl.Update ((float)(curPl++) / numPl);
		}
		obj->Optimize ();
		obj->InvalidateRenderData();
	}

	return true;
}
// Vtable functions
// Creates: A single Game Object via the Factory
GameObject *Object2Create ( void )
{
  List *GameObjectList = GetObjectList( );
  
  Node *node = InsertBackRaw( GameObjectList, sizeof( Object2 ) );
  GameObject *obj = &NODE_DATA( node, GameObject );
  obj->id = ID_Object2;
  return obj;
}
Beispiel #6
0
void Model::CalculateRadius ()
{
	vector<MdlObject*> objs = GetObjectList();
	radius=0.0f;
	for (int o=0;o<objs.size();o++) {
		MdlObject *obj = objs[o];
		Matrix objTransform;
		obj->GetFullTransform(objTransform);
		for(int v=0;v<obj->verts.size();v++){
			Vector3 tpos;
			objTransform.apply(&obj->verts[v].pos,&tpos);
			float r= (tpos-mid).length();
			if (radius < r) radius=r;
		}
	}
}
Beispiel #7
0
// Set target for client
void _Battle::ClientSetTarget(const _Item *Item, int Side, _Object *InitialTarget) {
	ClientPlayer->Character->Targets.clear();

	// Can't change self targets
	if(Item->TargetID == TargetType::SELF) {
		ClientPlayer->Character->Targets.push_back(ClientPlayer);
		return;
	}

	// Get list of objects on each side
	std::list<_Object *> ObjectList;
	GetObjectList(Side, ObjectList);
	auto Iterator = ObjectList.begin();

	// Get iterator to last target
	_Object *LastTarget = InitialTarget;
	if(ObjectList.size() && LastTarget && Item->CanTarget(ClientPlayer, LastTarget))
	   Iterator = std::find(ObjectList.begin(), ObjectList.end(), LastTarget);

	// Set up targets
	int TargetCount = Item->GetTargetCount();
	for(size_t i = 0; i < ObjectList.size(); i++) {

		// Check for valid target
		_Object *Target = *Iterator;
		if(Item->CanTarget(ClientPlayer, Target)) {

			// Add object to list of targets
			ClientPlayer->Character->Targets.push_back(Target);

			// Update count
			TargetCount--;
			if(TargetCount <= 0)
				break;
		}

		// Update target
		++Iterator;
		if(Iterator == ObjectList.end())
			Iterator = ObjectList.begin();
	}
}
Beispiel #8
0
// End battle and give rewards
void _Battle::ServerEndBattle() {

	// Get statistics for each side
	_BattleResult SideStats[2];
	std::list<_Object *> SideObjects[2];
	for(int Side = 0; Side < 2; Side++) {

		// Get a list of objects that are still in the battle
		GetObjectList(Side, SideObjects[Side]);

		// Loop through objects
		for(auto &Object : SideObjects[Side]) {

			// Keep track of players
			if(!Object->IsMonster())
				SideStats[Side].PlayerCount++;
			else
				SideStats[Side].MonsterCount++;

			if(Object->Fighter->JoinedBattle)
				SideStats[Side].JoinedCount++;

			// Tally alive objects
			if(Object->Character->IsAlive()) {
				SideStats[Side].AliveCount++;
				SideStats[Side].Dead = false;
			}

			// Sum experience and gold
			SideStats[Side].TotalExperienceGiven += Object->Monster->ExperienceGiven;

			// Calculate gold based on monster or player
			if(Object->IsMonster())
				SideStats[Side].TotalGoldGiven += Object->Monster->GoldGiven + Object->Fighter->GoldStolen;
			else
				SideStats[Side].TotalGoldGiven += Object->Character->Bounty + Object->Fighter->GoldStolen + (int)(Object->Character->Gold * BountyEarned + 0.5f);
		}

		SideStats[Side].TotalExperienceGiven = (int)std::ceil(SideStats[Side].TotalExperienceGiven * Difficulty[Side]);
		SideStats[Side].TotalGoldGiven = (int)std::ceil(SideStats[Side].TotalGoldGiven * Difficulty[Side]);
	}

	// Get winning side
	int WinningSide;
	if(SideStats[0].Dead && SideStats[1].Dead)
		WinningSide = -1;
	else if(SideStats[0].Dead)
		WinningSide = 1;
	else
		WinningSide = 0;

	// Check for a winning side
	if(WinningSide != -1 && SideObjects[WinningSide].size()) {

		// Divide up rewards
		for(int Side = 0; Side < 2; Side++) {
			int OtherSide = !Side;
			int DivideCount = SideStats[Side].AliveCount;
			if(DivideCount <= 0)
				continue;

			// Divide experience up
			if(SideStats[OtherSide].TotalExperienceGiven > 0) {
				SideStats[Side].ExperiencePerCharacter = SideStats[OtherSide].TotalExperienceGiven / DivideCount;
				if(SideStats[Side].ExperiencePerCharacter <= 0)
					SideStats[Side].ExperiencePerCharacter = 1;
			}

			// Divide gold up
			if(SideStats[OtherSide].TotalGoldGiven > 0) {
				SideStats[Side].GoldPerCharacter = SideStats[OtherSide].TotalGoldGiven / DivideCount;
				if(SideStats[Side].GoldPerCharacter <= 0)
					SideStats[Side].GoldPerCharacter = 1;
			}
		}

		// Get list of objects that get rewards
		std::list<_Object *> RewardObjects;
		int DropRate = 0;
		for(auto &Object : SideObjects[WinningSide]) {
			if(Object->Character->IsAlive()) {
				DropRate += Object->Character->DropRate;
				RewardObjects.push_back(Object);
			}
		}

		// Check for reward recipients
		if(RewardObjects.size() && !PVP) {

			// Convert winning side list to array
			std::vector<_Object *> ObjectArray { std::begin(RewardObjects), std::end(RewardObjects) };

			// Generate items drops
			std::list<uint32_t> ItemDrops;
			for(auto &Object : SideObjects[!WinningSide]) {
				if(Object->IsMonster())
					Stats->GenerateItemDrops(Object->Monster->DatabaseID, 1, DropRate, ItemDrops);
			}

			// Boss drops aren't divided up
			if(Boss) {
				for(auto &ItemID : ItemDrops) {
					for(auto &Object : RewardObjects) {
						Object->Fighter->ItemDropsReceived.push_back(ItemID);
					}
				}
			}
			// Give out drops randomly
			else {
				for(auto &ItemID : ItemDrops) {
					std::shuffle(ObjectArray.begin(), ObjectArray.end(), ae::RandomGenerator);
					_Object *Object = ObjectArray[0];
					Object->Fighter->ItemDropsReceived.push_back(ItemID);
				}
			}
		}
	}

	// Send data
	for(auto &Object : Objects) {
		Object->Controller->InputStates.clear();
		Object->Fighter->PotentialAction.Unset();
		Object->Character->Action.Unset();

		// Get rewards
		int ExperienceEarned = 0;
		int GoldEarned = 0;
		if(!Object->Character->IsAlive()) {
			if(PVP)
				Object->ApplyDeathPenalty(BountyEarned, Object->Character->Bounty);
			else
				Object->ApplyDeathPenalty(PLAYER_DEATH_GOLD_PENALTY, 0);
		}
		else {
			ExperienceEarned = SideStats[WinningSide].ExperiencePerCharacter;
			GoldEarned = SideStats[WinningSide].GoldPerCharacter;
			Object->Character->PlayerKills += SideStats[!WinningSide].PlayerCount;
			Object->Character->MonsterKills += SideStats[!WinningSide].MonsterCount;
			if(PVP && Object->Fighter->BattleSide == BATTLE_PVP_ATTACKER_SIDE) {
				if(BountyEarned) {
					Object->Character->Bounty += GoldEarned;
					if(Object->Character->Bounty) {
						std::string BountyMessage = "Player " + Object->Name + " now has a bounty of " + std::to_string(Object->Character->Bounty) + " gold!";
						Server->BroadcastMessage(nullptr, BountyMessage, "cyan");
						Server->Log << "[BOUNTY] " << BountyMessage << std::endl;
					}
				}
			}
		}

		// Start cooldown timer
		if(Object->Character->IsAlive() && Cooldown > 0.0 && Zone)
			Object->Character->BattleCooldown[Zone] = Cooldown;

		// Update stats
		int CurrentLevel = Object->Character->Level;
		Object->Character->UpdateExperience(ExperienceEarned);
		Object->Character->UpdateGold(GoldEarned);
		Object->Character->CalculateStats();
		int NewLevel = Object->Character->Level;
		if(NewLevel > CurrentLevel) {
			if(Object->Peer)
				Server->SendMessage(Object->Peer, std::string("You are now level " + std::to_string(NewLevel) + "!"), "gold");

			Object->Character->Health = Object->Character->MaxHealth;
			Object->Character->Mana = Object->Character->MaxMana;
		}

		// Write results
		ae::_Buffer Packet;
		Packet.Write<PacketType>(PacketType::BATTLE_END);
		Packet.Write<int>(Object->Character->PlayerKills);
		Packet.Write<int>(Object->Character->MonsterKills);
		Packet.Write<int>(Object->Character->GoldLost);
		Packet.Write<int>(Object->Character->Bounty);
		Packet.Write<int>(ExperienceEarned);
		Packet.Write<int>(GoldEarned);

		// Sort item drops
		std::unordered_map<uint32_t, int> SortedItems;
		for(auto &ItemID : Object->Fighter->ItemDropsReceived) {
			SortedItems[ItemID]++;
		}
		Object->Fighter->ItemDropsReceived.clear();

		// Write item count
		size_t ItemCount = SortedItems.size();
		Packet.Write<uint8_t>((uint8_t)ItemCount);

		// Write items
		for(auto &Iterator : SortedItems) {
			Packet.Write<uint32_t>(Iterator.first);
			Packet.Write<uint8_t>(0);
			Packet.Write<uint8_t>((uint8_t)Iterator.second);
			Object->Inventory->AddItem(Stats->Items.at(Iterator.first), 0, Iterator.second);
		}

		// Update bot goal
		if(Object->Character->Bot) {
			if(Scripting->StartMethodCall("Bot_Server", "DetermineNextGoal")) {
				Scripting->PushObject(Object);
				Scripting->MethodCall(1, 0);
				Scripting->FinishMethodCall();
			}
		}
		// Send info
		else if(Object->Peer) {
			Server->Network->SendPacket(Packet, Object->Peer);
			Server->SendHUD(Object->Peer);
		}
	}

	Deleted = true;
}
Beispiel #9
0
// Changes targets
void _Battle::ChangeTarget(int Direction, bool ChangeSides) {
	if(!ClientNetwork || !ClientPlayer->Fighter->PotentialAction.IsSet() || !ClientPlayer->Character->IsAlive() || !ClientPlayer->Character->Targets.size())
		return;

	// Can't change self targetting actions
	const _Item *Item = ClientPlayer->Fighter->PotentialAction.Item;
	if(Item->TargetID == TargetType::SELF)
		return;

	// Get current target side
	int BattleTargetSide = ClientPlayer->Character->Targets.front()->Fighter->BattleSide;

	// Change sides
	if(Item->TargetID == TargetType::ANY && ChangeSides)
		BattleTargetSide = !BattleTargetSide;

	// Get list of objects on target side
	std::list<_Object *> ObjectList;
	GetObjectList(BattleTargetSide, ObjectList);

	// Get iterator to current target
	auto Iterator = ObjectList.begin();
	if(ObjectList.size())
	   Iterator = std::find(ObjectList.begin(), ObjectList.end(), ClientPlayer->Character->Targets.front());

	// Get target count
	size_t TargetCount = ClientPlayer->Character->Targets.size();
	ClientPlayer->Character->Targets.clear();

	// Get max available targets
	size_t MaxTargets = 0;
	for(auto &Target : ObjectList) {
		if(Item->CanTarget(ClientPlayer, Target))
			MaxTargets++;
	}

	// Cap target count
	TargetCount = std::min(TargetCount, MaxTargets);

	// Search for valid target
	_Object *NewTarget = nullptr;
	while(TargetCount) {

		// Wrap around
		if(Iterator == ObjectList.end())
			Iterator = ObjectList.begin();

		// Update target
		if(Direction > 0) {
			++Iterator;
			if(Iterator == ObjectList.end())
				Iterator = ObjectList.begin();

			NewTarget = *Iterator;
		}
		else if(Direction < 0) {
			if(Iterator == ObjectList.begin()) {
				Iterator = ObjectList.end();
				--Iterator;
			}
			else {
				--Iterator;
			}

			NewTarget = *Iterator;
		}
		else
			NewTarget = *Iterator;

		// Check break condition
		if(Item->CanTarget(ClientPlayer, NewTarget)) {
			ClientPlayer->Character->Targets.push_back(NewTarget);

			// Update count
			TargetCount--;

			// Start moving down after first target found
			Direction = 1;
		}
		else if(ChangeSides)
			Direction = 1;
	}
}
Beispiel #10
0
/**
 * @function GUI_DrawObjects
 * @brief handle all object (user event, refresh)
 * @param none
 * @return none
 */
void GUI_DrawObjects(void) {

  g_obj_st *ptr = NULL;
  coord_t newX, newY;

  /*reset signal & read touch screen; only once for all object*/
  signal = 0;
  TouchScreenRead(&newX, &newY);

  /*small hysteresis to compensate touchscreen noise*/
  #define TOUCH_THRES_HYS 2
  if(newX < 0 || newY < 0) {
    x = y = -1;
  }
  else {

    if(x < 0 || y < 0) {
      x = newX;
      y = newY;
    }
    else if(P2D_Abs(newX - x) > TOUCH_THRES_HYS || P2D_Abs(newY - y) > TOUCH_THRES_HYS) {
      x = newX;
      y = newY;
    }
  }


  /*get the object list, according to the active layer*/
  ptr = GetObjectList();

  /*process notification blink*/
  if(IsTimerElapsed(tmrBlink)) {
    bBlink = !bBlink;
    tmrBlink = GetPeriodicTimeout(500);
    while(ptr != NULL) {
      GUI_ObjSetBlink(ptr, bBlink);
      ptr = ptr->next;
    }
  }

  /*process each generic object of the current layer*/
  while(ptr != NULL) {

    /*handle user interaction*/
    HandleTouchEvent(x, y, ptr);

    /*handle object signals*/
    HandleSignal(ptr);

    if(ptr->obj != NULL) {

      /*launch the object task, if any*/
      if(ptr->task != NULL) ptr->task(ptr, ptr->obj);

      /*redraw the object, only if needed*/
      if(GUI_ObjIsNeedRefresh(ptr) && ptr->draw != NULL) {
        P2D_SetClip(&(ptr->rec));
        ptr->draw(ptr, ptr->obj);
        GUI_ObjSetNeedRefresh(ptr, false);
      }
    }

    /*next object*/
    ptr = ptr->next;
  }

  /**
   * execute, if any, the top layer task
   * pInternalTask may close the top layer and return a signal;
   * when closing the top layer, pInternalTask becomes NULL
   * this signal will be given to the user at end of GUI_DrawObjects()
   */
  if(pInternalTask != NULL) signal = pInternalTask(signal);
  
  /**
   * Save the last non null signal (for slave remote)
   */
  if(signal != 0 && pInternalTask == NULL) {
    lastSignal = signal;
  }
  
  /**
   * execute the user task, if no internal task is running
   * DO NOT concate this condition with the previous one in a if/else statement !
   */
  if(pInternalTask == NULL) {
    if(pUserTask != NULL) pUserTask(signal);
  }
}