Esempio n. 1
0
func (self *Session) Exec() {
	defer events.Unregister(self.pc)
	defer model.Logout(self.pc)

	self.WriteLine("Welcome, " + self.pc.GetName())
	self.PrintRoom()

	// Main routine in charge of actually reading input from the connection object,
	// also has built in throttling to limit how fast we are allowed to process
	// commands from the user.
	go func() {
		defer func() {
			self.panicChannel <- recover()
		}()

		throttler := utils.NewThrottler(200 * time.Millisecond)

		for {
			mode := <-self.inputModeChannel
			prompter := <-self.prompterChannel
			input := ""

			switch mode {
			case CleanUserInput:
				input = utils.GetUserInputP(self.conn, prompter, self.user.GetColorMode())
			case RawUserInput:
				input = utils.GetRawUserInputP(self.conn, prompter, self.user.GetColorMode())
			default:
				panic("Unhandled case in switch statement (userInputMode)")
			}

			throttler.Sync()
			self.userInputChannel <- input
		}
	}()

	// Main loop
	for {
		input := self.getUserInputP(RawUserInput, self)
		if input == "" || input == "logout" || input == "quit" {
			return
		}

		if input == "." {
			input = self.lastInput
		}

		self.lastInput = input

		if strings.HasPrefix(input, "/") {
			self.handleCommand(utils.Argify(input[1:]))
		} else {
			self.handleAction(utils.Argify(input))
		}
	}
}
Esempio n. 2
0
func manageSpawner(spawner types.Spawner) {
	throttler := utils.NewThrottler(5 * time.Second)
	go func() {
		for {
			rooms := model.GetAreaRooms(spawner.GetAreaId())

			if len(rooms) > 0 {
				npcs := model.GetSpawnerNpcs(spawner.GetId())
				diff := spawner.GetCount() - len(npcs)

				for diff > 0 && len(rooms) > 0 {
					room := rooms[utils.Random(0, len(rooms)-1)]
					npc := model.CreateNpc(spawner.GetName(), room.GetId(), spawner.GetId())
					npc.SetHealth(spawner.GetHealth())
					manageNpc(npc)
					diff--
				}
			}

			throttler.Sync()
		}
	}()
}
Esempio n. 3
0
func init() {
	_listeners = map[EventReceiver]chan Event{}
	eventMessages = make(chan interface{}, 1)

	go func() {
		for message := range eventMessages {
			switch msg := message.(type) {
			case register:
				_listeners[msg.Receiver] = msg.Channel
			case unregister:
				delete(_listeners, msg.Receiver)
			case broadcast:
				for char, channel := range _listeners {
					if msg.Event.IsFor(char) {
						go func(c chan Event) {
							c <- msg.Event
						}(channel)
					}
				}
			default:
				panic("Unhandled event message")
			}
		}

		_listeners = nil
	}()

	go func() {
		throttler := utils.NewThrottler(1 * time.Second)

		for {
			throttler.Sync()
			Broadcast(TickEvent{})
		}
	}()
}
Esempio n. 4
0
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")
			}
		}
	}()
}