func (g *Game) internalCreatureTeleport(_creature pul.ICreature, _from pul.ITile, _to pul.ITile) (ret int) { ret = RET_NOERROR if _from == nil || _to == nil { ret = RET_NOTPOSSIBLE } else { // Move creature object to destination tile if ret = _from.RemoveCreature(_creature, true); ret == RET_NOTPOSSIBLE { return } if ret = _to.AddCreature(_creature, false); ret == RET_NOTPOSSIBLE { _from.AddCreature(_creature, false) // Something went wrong, put creature back on old tile return } _creature.SetTile(_to) // Tell creatures this creature has been teleported g.mutexCreatureList.RLock() defer g.mutexCreatureList.RUnlock() for _, value := range g.Creatures { if value != nil { value.OnCreatureMove(_creature, _from, _to, true) } } } // No error, played succesfully teleported if ret == RET_NOERROR { ret = RET_PLAYERISTELEPORTED } return }
func (g *Game) internalCreatureSay(_creature pul.ICreature, _speakType int, _message string) bool { list := make(pul.CreatureList) if _speakType == pnet.SPEAK_YELL { position := _creature.GetPosition() // Get position of speaker g.mutexPlayerList.RLock() defer g.mutexPlayerList.RUnlock() for _, player := range g.Players { if player != nil { if position.IsInRange3p(player.GetPosition(), pos.NewPositionFrom(27, 21, 0)) { list[player.GetUID()] = player } } } } else { list = _creature.GetVisibleCreatures() } // Send chat message to all visible players for _, creature := range list { if creature.GetType() == CTYPE_PLAYER { player := creature.(*Player) // player.sendCreatureSay(_creature, _speakType, _message) player.sendToChannel(_creature, _speakType, _message, pnet.CHANNEL_LOCAL, 0) } } return true }
// AddCreature adds a new active creature to this tile func (t *Tile) AddCreature(_creature pul.ICreature, _checkEvents bool) (ret int) { ret = RET_NOERROR if _checkEvents && t.Events.Len() > 0 { var i int = 0 for e := t.Events.Front(); e != nil; e = e.Next() { event, valid := e.Value.(ITileEvent) if valid { ret = event.OnCreatureEnter(_creature, ret) } if ret == RET_NOTPOSSIBLE { return } i++ } } _, found := t.Creatures[_creature.GetUID()] if !found { t.Creatures[_creature.GetUID()] = _creature } return }
func (g *Game) internalCreatureChangeVisible(_creature pul.ICreature, _visible bool) { list := _creature.GetVisibleCreatures() for _, tmpCreature := range list { if tmpCreature.GetType() == CTYPE_PLAYER { tmpCreature.(*Player).sendCreatureChangeVisibility(_creature, _visible) } } }
func (n *Npc) OnCreatureDisappear(_creature pul.ICreature, _isLogout bool) { // Check if _creature is a Player, otherwise return if _creature.GetType() != CTYPE_PLAYER { return } n.RemoveVisibleCreature(_creature) }
func (p *Player) sendCreatureChangeVisibility(_creature pul.ICreature, _visible bool) { if _creature.GetUID() != p.GetUID() { if _visible { p.AddVisibleCreature(_creature) } else if !p.HasFlag(PlayerFlag_CanSenseInvisibility) { p.RemoveVisibleCreature(_creature) } } }
func (e *Warp) OnCreatureEnter(_creature pul.ICreature, _prevRet int) (ret int) { currentTile := _creature.GetTile() destinationTile, found := g_map.GetTileFromPosition(e.destination) if found { ret = g_game.internalCreatureTeleport(_creature, currentTile, destinationTile) } else { ret = RET_NOTPOSSIBLE } return }
func (p *Player) OnCreatureDisappear(_creature pul.ICreature, _isLogout bool) { if _creature.GetUID() == p.GetUID() { return } if _isLogout { // Check if creature is in friendlist p.UpdateFriend(_creature.GetName(), false) } p.RemoveVisibleCreature(_creature) }
func (g *Game) OnPlayerMove(_creature pul.ICreature, _direction int, _sendMap bool) { ret := g.OnCreatureMove(_creature, _direction) player := _creature.(*Player) if ret == RET_NOTPOSSIBLE { player.sendCreatureMove(_creature, _creature.GetTile(), _creature.GetTile()) } else if ret == RET_PLAYERISTELEPORTED { player.sendPlayerWarp() player.sendMapData(DIR_NULL) } else { player.sendMapData(_direction) } }
func (p *Player) OnCreatureMove(_creature pul.ICreature, _from pul.ITile, _to pul.ITile, _teleport bool) { if _creature.GetUID() == p.GetUID() { p.lastStep = PUSYS_TIME() return } from := _from.(*Tile) to := _to.(*Tile) canSeeFromTile := CanSeePosition(p.GetPosition(), from.Position) canSeeToTile := CanSeePosition(p.GetPosition(), to.Position) if canSeeFromTile && !canSeeToTile { // Leaving viewport p.sendCreatureMove(_creature, from, to) p.RemoveVisibleCreature(_creature) _creature.RemoveVisibleCreature(p) } else if canSeeToTile && !canSeeFromTile { // Entering viewport p.AddVisibleCreature(_creature) _creature.RemoveVisibleCreature(p) p.sendCreatureMove(_creature, from, to) } else { // Moving inside viewport p.AddVisibleCreature(_creature) _creature.AddVisibleCreature(p) p.sendCreatureMove(_creature, from, to) } }
func (n *Npc) RemoveVisibleCreature(_creature pul.ICreature) { // Check if _creature is a Player, otherwise return if _creature.GetType() != CTYPE_PLAYER { return } // Check if the player was interacting with this npc if n.HasInteractingPlayer(_creature.(*Player)) { n.RemoveInteractingPlayer(_creature.(*Player)) } // No need to check if the key actually exists because Go is awesome // http://golang.org/doc/effective_go.html#maps delete(n.VisibleCreatures, _creature.GetUID()) }
func (n *Npc) OnCreatureAppear(_creature pul.ICreature, _isLogin bool) { // Check if _creature is a Player, otherwise return if _creature.GetType() != CTYPE_PLAYER { return } canSeeCreature := CanSeeCreature(n, _creature) if !canSeeCreature { return } // We're checking the existence of _creature inside the AddVisibleCreature method // so no need to check here n.AddVisibleCreature(_creature) _creature.AddVisibleCreature(n) }
// RemoveCreature removes an active creature from this tile func (t *Tile) RemoveCreature(_creature pul.ICreature, _checkEvents bool) (ret int) { ret = RET_NOERROR if _checkEvents && t.Events.Len() > 0 { for e := t.Events.Front(); e != nil; e = e.Next() { event, valid := e.Value.(ITileEvent) if valid { ret = event.OnCreatureLeave(_creature, ret) } if ret == RET_NOTPOSSIBLE { return } } } delete(t.Creatures, _creature.GetUID()) return }
// CheckMovement checks if a creature can move to this tile func (t *Tile) CheckMovement(_creature pul.ICreature, _dir int) int { movement := _creature.GetMovement() blocking := t.Blocking if blocking != TILEBLOCK_WALK { if blocking == TILEBLOCK_BLOCK || (blocking == TILEBLOCK_SURF && movement != MOVEMENT_SURF) || (blocking == TILEBLOCK_TOP && _dir == DIR_SOUTH) || (blocking == TILEBLOCK_BOTTOM && _dir == DIR_NORTH) || (blocking == TILEBLOCK_LEFT && _dir == DIR_EAST) || (blocking == TILEBLOCK_RIGHT && _dir == DIR_WEST) || (blocking == TILEBLOCK_TOPLEFT && (_dir == DIR_EAST || _dir == DIR_SOUTH)) || (blocking == TILEBLOCK_TOPRIGHT && (_dir == DIR_WEST || _dir == DIR_SOUTH)) || (blocking == TILEBLOCK_BOTTOMLEFT && (_dir == DIR_EAST || _dir == DIR_NORTH)) || (blocking == TILEBLOCK_BOTTOMRIGHT && (_dir == DIR_WEST || _dir == DIR_NORTH)) { return RET_NOTPOSSIBLE } } return RET_NOERROR }
func (n *Npc) AddVisibleCreature(_creature pul.ICreature) { // Check if _creature is a Player, otherwise return if _creature.GetType() != CTYPE_PLAYER { return } if _, found := n.VisibleCreatures[_creature.GetUID()]; !found { n.VisibleCreatures[_creature.GetUID()] = _creature } }
func (g *Game) OnCreatureTurn(_creature pul.ICreature, _direction int) { if _creature.GetDirection() != _direction { _creature.SetDirection(_direction) visibleCreatures := _creature.GetVisibleCreatures() for _, value := range visibleCreatures { value.OnCreatureTurn(_creature) } } }
func (n *Npc) OnCreatureMove(_creature pul.ICreature, _from pul.ITile, _to pul.ITile, _teleport bool) { // Check if _creature is a Player, otherwise return if _creature.GetType() != CTYPE_PLAYER { return } canSeeFromTile := CanSeePosition(n.GetPosition(), _from.GetPosition()) canSeeToTile := CanSeePosition(n.GetPosition(), _to.GetPosition()) if canSeeFromTile && !canSeeToTile { // Leaving viewport n.RemoveVisibleCreature(_creature) _creature.RemoveVisibleCreature(n) } else if canSeeToTile && !canSeeFromTile { // Entering viewport n.AddVisibleCreature(_creature) _creature.RemoveVisibleCreature(n) } else { // Moving inside viewport n.AddVisibleCreature(_creature) _creature.AddVisibleCreature(n) } }
func (p *Player) OnCreatureAppear(_creature pul.ICreature, _isLogin bool) { if _creature.GetUID() == p.GetUID() { return } if _isLogin { // Check if creature is in friendlist p.UpdateFriend(_creature.GetName(), true) } canSeeCreature := CanSeeCreature(p, _creature) if !canSeeCreature { return } // We're checking inside the AddVisibleCreature method so no need to check here p.AddVisibleCreature(_creature) _creature.AddVisibleCreature(p) }
func (g *Game) AddCreature(_creature pul.ICreature) { // TODO: Maybe only take the creatues from the area the new creature is in. This saves some extra iterating g.mutexCreatureList.Lock() defer g.mutexCreatureList.Unlock() for _, value := range g.Creatures { value.OnCreatureAppear(_creature, true) } g.Creatures[_creature.GetUID()] = _creature if _creature.GetType() == CTYPE_PLAYER { g.mutexPlayerList.Lock() defer g.mutexPlayerList.Unlock() g.Players[_creature.GetUID()] = _creature.(*Player) // Join default channels g.Chat.AddUserToChannel(_creature.(*Player), pnet.CHANNEL_WORLD) g.Chat.AddUserToChannel(_creature.(*Player), pnet.CHANNEL_TRADE) } }
func (c *Connection) SendCreatureRemove(_creature pul.ICreature) { if _creature.GetUID() != c.Owner.GetUID() { msg := pnetmsg.NewCreatureRemoveMessage(_creature) c.SendMessage(msg) } }
func (n *Npc) OnCreatureTurn(_creature pul.ICreature) { // Check if _creature is a Player, otherwise return if _creature.GetType() != CTYPE_PLAYER { return } }
func (g *Game) checkForWildEncounter(_creature pul.ICreature) { if _creature.GetType() == CTYPE_PLAYER { // Do some checkin' } }
func (g *Game) OnCreatureMove(_creature pul.ICreature, _direction int) (ret int) { ret = RET_NOTPOSSIBLE if !CreatureCanMove(_creature) { return } currentTile := _creature.GetTile() destinationPosition := currentTile.GetPosition() switch _direction { case DIR_NORTH: destinationPosition.Y -= 1 case DIR_SOUTH: destinationPosition.Y += 1 case DIR_WEST: destinationPosition.X -= 1 case DIR_EAST: destinationPosition.X += 1 } // Check if destination tile exists destinationTile, ok := g_map.GetTileFromPosition(destinationPosition) if !ok { return } // Check if we can move to the destination tile if ret = destinationTile.CheckMovement(_creature, _direction); ret == RET_NOTPOSSIBLE { return } // Update position _creature.SetTile(destinationTile) // fmt.Printf("[%v] From (%v,%v) To (%v,%v)\n", _creature.GetName(), currentTile.Position.X, currentTile.Position.Y, destinationPosition.X, destinationPosition.Y) // Tell creatures this creature has moved g.mutexCreatureList.RLock() defer g.mutexCreatureList.RUnlock() for _, value := range g.Creatures { if value != nil { value.OnCreatureMove(_creature, currentTile, destinationTile, false) } } // Move creature object to destination tile if ret = currentTile.RemoveCreature(_creature, true); ret == RET_NOTPOSSIBLE { return } if ret = destinationTile.AddCreature(_creature, true); ret == RET_NOTPOSSIBLE { currentTile.AddCreature(_creature, false) // Something went wrong, put creature back on old tile _creature.SetTile(currentTile) return } // If ICreature is a player type we can check for wild encounter g.checkForWildEncounter(_creature) return }
// Returns true if the passed creature can move func CreatureCanMove(_creature pul.ICreature) bool { canMove := (_creature.GetTimeSinceLastMove() >= _creature.GetMovementSpeed()) return canMove }
func (p *Player) OnCreatureTurn(_creature pul.ICreature) { if _creature.GetUID() != p.GetUID() { p.sendCreatureTurn(_creature) } }
// CanSeeCreature checks if 2 creatures are near each others viewport func CanSeeCreature(_self pul.ICreature, _other pul.ICreature) bool { return CanSeePosition(_self.GetPosition(), _other.GetPosition()) }
func (c *Creature) KnowsVisibleCreature(_creature pul.ICreature) (found bool) { _, found = c.VisibleCreatures[_creature.GetUID()] return }
func (c *Creature) RemoveVisibleCreature(_creature pul.ICreature) { if _, found := c.VisibleCreatures[_creature.GetUID()]; !found { c.VisibleCreatures[_creature.GetUID()] = _creature } }
func (p *Player) AddVisibleCreature(_creature pul.ICreature) { if _, found := p.VisibleCreatures[_creature.GetUID()]; !found { p.VisibleCreatures[_creature.GetUID()] = _creature p.sendCreatureAdd(_creature) } }
func (p *Player) RemoveVisibleCreature(_creature pul.ICreature) { // No need to check if the key actually exists because Go is awesome // http://tip.golang.org/doc/effective_go.html#maps delete(p.VisibleCreatures, _creature.GetUID()) p.sendCreatureRemove(_creature) }