Beispiel #1
0
func (api apiHelper) FetchRoom(c *gin.Context) (*g.Room, error) {
	roomId := c.Param("room")
	room := g.FetchRoom(g.RefID(uuid.FromStringOrNil(roomId)))
	if room == nil {
		return nil, errors.New("room not found")
	}

	return room, nil
}
Beispiel #2
0
func playerIDHeaderRequired() gin.HandlerFunc {
	return func(c *gin.Context) {
		playerID := apiHelper{}.GetRequestPlayerID(c)
		if playerID.Equal(g.RefID(uuid.Nil)) {
			c.JSON(http.StatusUnauthorized, gin.H{})
			c.Abort()
		} else {
			c.Next()
		}
	}
}
Beispiel #3
0
func (api apiV1C) getPlayerLocation(c *gin.Context) {
	room, err := api.helpers.FetchRoom(c)

	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"errors": err.Error()})
		return
	}

	currentPlayer := room.GetPlayer(api.helpers.GetRequestPlayerID(c))
	locationPlayer := room.GetPlayer(g.RefID(uuid.FromStringOrNil(c.Param("player"))))
	if currentPlayer == nil || locationPlayer == nil {
		c.JSON(http.StatusForbidden, gin.H{"errors": "player not found"})
		return
	}

	if currentPlayer.RefID() != locationPlayer.RefID() {
		c.JSON(http.StatusForbidden, gin.H{"errors": "incorrect player uuid"})
		return
	}

	location := room.FindPlayerLocation(locationPlayer)
	if location == nil {
		c.JSON(http.StatusInternalServerError, gin.H{"errors": "location incorrect"})
		return
	}

	type monsterRepresent struct {
		*g.RefIDObj
		g.PosObj
		SubType string `json:"subType"`
		Name    string `json:"name"`
		HP      int    `json:"hp"`
	}
	monsters := []apiData{}
	for _, m := range room.Monsters().InLocation(location).Lives() {
		monster := monsterRepresent{
			&m.RefIDObj,
			m.PosObj,
			m.Render,
			m.Name(),
			m.HP,
		}
		monsters = append(monsters, serializeToAPIData(monster))
	}

	type placeItemRepresent struct {
		*g.RefIDObj
		g.PosObj
		Name string `json:"name"`
	}
	locationItems := []apiData{}
	for _, item := range room.PlaceItems() {
		if item.InLocation(location) {
			item := placeItemRepresent{
				&item.RefIDObj,
				item.PosObj,
				item.String(),
			}
			locationItems = append(locationItems, serializeToAPIData(item))
		}
	}

	type weaponRepresent struct {
		RefID       uuid.UUID `json:"id"`
		Name        string    `json:"name"`
		Description string    `json:"description"`
	}

	rightHandWeapons := make([]weaponRepresent, 0)
	var rightHandWeapon weaponRepresent
	{
		weapon := locationPlayer.CurrentWeapon()
		rightHandWeapon = weaponRepresent{uuid.UUID(weapon.RefID()), weapon.Name, weaponDescription(&weapon)}
	}

	for _, weapon := range locationPlayer.GetWeapons() {
		rightHandWeapons = append(rightHandWeapons, weaponRepresent{uuid.UUID(weapon.RefID()), weapon.Name, weaponDescription(weapon)})
	}

	type inventoryRepresent struct {
		RefID       uuid.UUID `json:"id"`
		Name        string    `json:"name"`
		Description string    `json:"description"`
	}
	inventoryItems := make([]inventoryRepresent, 0)
	for _, item := range locationPlayer.GetItems() {
		inventoryItems = append(inventoryItems, inventoryRepresent{uuid.UUID(item.RefID()), item.Name, item.Description})
	}

	playerRepresent := struct {
		*g.RefIDObj
		g.PosObj
		HP        int                  `json:"hitPoints"`
		MP        int                  `json:"manaPoints"`
		Inventory []inventoryRepresent `json:"inventory"`
		Weapons   []weaponRepresent    `json:"weapons"`
		RightHand weaponRepresent      `json:"rightHand"`
		Steps     int                  `json:"steps"`
	}{
		&locationPlayer.RefIDObj,
		locationPlayer.PosObj,
		locationPlayer.HP,
		locationPlayer.MP,
		inventoryItems,
		rightHandWeapons,
		rightHandWeapon,
		locationPlayer.Steps(),
	}

	response := gin.H{
		"location":    serializeToAPIData(location),
		"monsters":    monsters,
		"player":      serializeToAPIData(playerRepresent),
		"items":       locationItems,
		"statusPanel": gin.H{"letter": "Lasciate ogni speranza, voi ch'entrate"},
		"finished":    room.IsFinished(),
	}
	c.JSON(http.StatusOK, response)
}
Beispiel #4
0
func (api apiHelper) GetRequestPlayerID(c *gin.Context) g.RefID {
	playerID := c.Request.Header.Get(HeaderPlayerID)

	return g.RefID(uuid.FromStringOrNil(playerID))
}
Beispiel #5
0
func (api apiV1C) playerCommands(c *gin.Context) {
	room, err := api.helpers.FetchRoom(c)

	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"errors": err.Error()})
		return
	}

	player := room.GetPlayer(api.helpers.GetRequestPlayerID(c))
	if player == nil {
		c.JSON(http.StatusForbidden, gin.H{"errors": "player not found"})
		return
	}

	location := room.FindPlayerLocation(player)
	if location == nil {
		c.JSON(http.StatusInternalServerError, gin.H{"errors": "location incorrect"})
		return
	}

	if room.IsFinished() {
		c.JSON(http.StatusBadRequest, gin.H{"errors": "game finished"})
		return
	}

	var action apiPlayerCommands
	if err := c.BindJSON(&action); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"errors": err.Error()})
		return
	}
	if !player.IsLive() {
		c.JSON(http.StatusBadRequest, gin.H{"errors": "player is dead"})
		return
	}

	if len(action.Commands) == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"errors": "commands empty"})
		return
	}

	result := make([]string, 0)
	command := action.Commands[0]

	switch command["type"] {
	case "move":
		if direct, ok := availableDirects[command["direct"]]; !ok {
			c.JSON(http.StatusBadRequest, gin.H{"errors": "unknown command"})
			return
		} else {
			player.ResetStats()
			for idx := range player.SideEffects {
				player.SideEffects[idx].Exec(player, &player.SideEffects[idx])
				result = append(result, "Применен эффект: "+player.SideEffects[idx].Name())
			}
			player.PackSideEffects()
			result = append(result, movement.MovePlayer(room, location, player, direct)...)
		}
	case "change-right-hand":
		weaponID, err := uuid.FromString(command["weaponID"])
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"errors": "invalid weaponID"})
			return
		}
		weapon := player.GetWeapon(g.RefID(weaponID))
		if weapon == nil {
			c.JSON(http.StatusBadRequest, gin.H{"errors": "invalid weaponID"})
			return
		}

		if err := player.ChangeRightHandWeapon(weapon.RefID()); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"errors": err})
			return
		}
		result = append(result, "Смена оружия: "+weapon.Name)
	case "use-item":
		itemID, err := uuid.FromString(command["itemID"])
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"errors": "invalid itemID"})
			return
		}
		item := player.GetItem(g.RefID(itemID))
		if item.Usable {
			result = append(result, g.PlayerUseItem(player, item)...)
		}
	default:
		c.JSON(http.StatusBadRequest, gin.H{"errors": "unknown command"})
		return
	}

	if room.IsFinished() {
		c.JSON(http.StatusCreated, gin.H{"result": result})
		return
	}

	for idx, placeItem := range room.PlaceItems() {
		if player.PosEqual(placeItem.PosObj) {
			player.AddToInventory(placeItem.Item)
			room.SetNullItem(idx)
			if item, ok := placeItem.Item.(fmt.Stringer); ok {
				result = append(result, "Подобран предмет: "+item.String())
			} else {
				result = append(result, "Подобран предмет...")
			}
		}
	}

	for _, monster := range room.Monsters().InLocation(room.FindPlayerLocation(player)).Lives() {
		result = append(result, npc.MoveToPlayer(room, location, monster, player)...)
	}

	c.JSON(http.StatusCreated, gin.H{"result": result})
}