func handleLock(s *Session, arg string, locked bool) { dir := types.StringToDirection(arg) if dir == types.DirectionNone { s.printError("Invalid direction") } else { s.GetRoom().SetLocked(dir, locked) events.Broadcast(events.LockEvent{ RoomId: s.pc.GetRoomId(), Exit: dir, Locked: locked, }) // Lock on both sides location := s.GetRoom().NextLocation(dir) otherRoom := model.GetRoomByLocation(location, s.GetRoom().GetZoneId()) if otherRoom != nil { otherRoom.SetLocked(dir.Opposite(), locked) events.Broadcast(events.LockEvent{ RoomId: otherRoom.GetId(), Exit: dir.Opposite(), Locked: locked, }) } } }
func MoveCharacterToRoom(character types.Character, newRoom types.Room) { oldRoomId := character.GetRoomId() character.SetRoomId(newRoom.GetId()) oldRoom := GetRoom(oldRoomId) // Leave dir := DirectionBetween(oldRoom, newRoom) events.Broadcast(events.LeaveEvent{Character: character, RoomId: oldRoomId, Direction: dir}) // Enter dir = DirectionBetween(newRoom, oldRoom) events.Broadcast(events.EnterEvent{Character: character, RoomId: newRoom.GetId(), Direction: dir}) }
func doCombatStop(attacker types.Character) { info := fights[attacker] if info.Defender != nil { delete(fights, attacker) events.Broadcast(events.CombatStopEvent{Attacker: attacker, Defender: info.Defender}) } }
func Logout(character types.PC) { character.SetOnline(false) events.Broadcast(events.LogoutEvent{Character: character}) }
func Login(character types.PC) { character.SetOnline(true) events.Broadcast(events.LoginEvent{Character: character}) }
func Emote(from types.Character, message string) { events.Broadcast(events.EmoteEvent{Character: from, Emote: message}) }
func Say(from types.Character, message string) { events.Broadcast(events.SayEvent{Character: from, Message: message}) }
func Tell(from types.Character, to types.Character, message string) { events.Broadcast(events.TellEvent{From: from, To: to, Message: message}) }
func CreateNpc(name string, roomId types.Id, spawnerId types.Id) types.NPC { npc := db.NewNpc(name, roomId, spawnerId) events.Broadcast(events.EnterEvent{Character: npc, RoomId: roomId, Direction: types.DirectionNone}) return npc }
func CreatePlayerCharacter(name string, userId types.Id, startingRoom types.Room) types.PC { pc := db.NewPc(name, userId, startingRoom.GetId()) events.Broadcast(events.EnterEvent{Character: pc, RoomId: startingRoom.GetId(), Direction: types.DirectionNone}) return pc }
func init() { fights = map[types.Character]combatInfo{} combatMessages = make(chan interface{}, 1) go func() { defer func() { recover() }() throttler := utils.NewThrottler(combatInterval) for { throttler.Sync() combatMessages <- combatTick(true) } }() go func() { for message := range combatMessages { Switch: switch m := message.(type) { case combatTick: for a, info := range fights { d := info.Defender if a.GetRoomId() == d.GetRoomId() { var power int skill := info.Skill if skill == nil { power = utils.Random(1, 10) } else { power = skill.GetPower() variance := utils.Random(-skill.GetVariance(), skill.GetVariance()) power += variance } d.Hit(power) events.Broadcast(events.CombatEvent{Attacker: a, Defender: d, Skill: skill, Power: power}) if d.GetHitPoints() <= 0 { Kill(d) } } else { doCombatStop(a) } } case combatStart: oldInfo, found := fights[m.Attacker] if m.Defender == oldInfo.Defender { break } if found { doCombatStop(m.Attacker) } fights[m.Attacker] = combatInfo{ Defender: m.Defender, Skill: m.Skill, } events.Broadcast(events.CombatStartEvent{Attacker: m.Attacker, Defender: m.Defender}) case combatStop: doCombatStop(m.Attacker) case combatQuery: _, found := fights[m.Character] if found { m.Ret <- true } else { for _, info := range fights { if info.Defender == m.Character { m.Ret <- true break Switch } } m.Ret <- false } default: panic("Unhandled combat message") } } }() }
func Kill(char types.Character) { clearCombat(char) events.Broadcast(events.DeathEvent{Character: char}) }