Пример #1
0
func manageNpc(npc types.NPC) {
	eventChannel := events.Register(npc)

	go func() {
		defer events.Unregister(npc)

		for {
			event := <-eventChannel
			switch e := event.(type) {
			case events.TickEvent:
				if npc.GetRoaming() {
					room := model.GetRoom(npc.GetRoomId())
					exits := room.GetExits()
					exitToTake := utils.Random(0, len(exits)-1)
					model.MoveCharacter(npc, exits[exitToTake])
				}
			case events.CombatStartEvent:
				if npc == e.Defender {
					combat.StartFight(npc, nil, e.Attacker)
				}
			case events.CombatStopEvent:
				if npc == e.Defender {
					combat.StopFight(npc)
				}
			case events.DeathEvent:
				if npc == e.Character {
					model.DeleteCharacter(npc.GetId())
					return
				}
			}
		}
	}()
}
Пример #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()
		}
	}()
}
Пример #3
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")
			}
		}
	}()
}