def set_tile_values(self, default, x, y, type=None, reset=True): if reset: self.tile[x][y] = {} if type is not None: if type == 'trap': temp_tile = game.tiles.find_trap() else: temp_tile = game.tiles.get_tile_from_type(default, type) else: temp_tile = game.tiles.get_tile(default) self.tile[x][y].update({'icon': temp_tile.icon, 'name': temp_tile.name, 'type': temp_tile.type, 'article': temp_tile.article}) self.tile[x][y].update({'color': temp_tile.color, 'dark_color': temp_tile.dark_color}) self.tile[x][y].update({'dark_back_color': temp_tile.dark_back_color}) if temp_tile.blocked: self.tile[x][y].update({'blocked': True}) if temp_tile.block_sight: self.tile[x][y].update({'block_sight': True}) if temp_tile.flags: for i in temp_tile.flags: self.tile[x][y].update({i: True}) back_lerp = round(libtcod.random_get_float(game.rnd, 0, 1), 1) back_color = libtcod.color_lerp(temp_tile.back_color_high, temp_tile.back_color_low, back_lerp) if temp_tile.color_low != libtcod.black: fore_lerp = round(libtcod.random_get_float(game.rnd, 0, 1), 1) fore_color = libtcod.color_lerp(temp_tile.color, temp_tile.color_low, fore_lerp) else: fore_color = temp_tile.color if self.tile_is_animated(x, y): self.tile[x][y].update({'back_light_color': temp_tile.back_color_high, 'back_dark_color': temp_tile.back_color_low, 'lerp': back_lerp}) else: self.tile[x][y].update({'color': fore_color, 'back_light_color': back_color, 'back_dark_color': libtcod.color_lerp(libtcod.black, back_color, 0.2), 'lerp': back_lerp})
def __init__(self, x, y, decay=0.1, velocity=1.0, angle=None, random_decay=True, bounce=False, color=None): self.x = x self.y = y self.decay = decay self.can_bounce = bounce if random_decay: self.decay += libtcod.random_get_float(0, -0.05, 0.05) self.velocity = velocity self.dead = False if angle == None: self.angle = math.atan2(float(-y), float(-x)) self.angle += libtcod.random_get_float(0, -3.14159, 3.14159) else: self.angle = angle self.dir_x = math.cos(self.angle * self.velocity) self.dir_y = math.sin(self.angle * self.velocity) self.color = uniform_intensity_burst(color)
def render_all(): global color_light_wall global color_light_ground map_rng = libtcod.random_new_from_seed(1, algo=libtcod.RNG_MT) #go through all tiles, and set their background color for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): wall = dungeon_map[x][y].block_sight if wall: libtcod.console_put_char_ex( con, x, y, WALL_CONST, color_dark_wall, libtcod.light_grey * libtcod.random_get_float(map_rng, 0.7, 0.8)) else: libtcod.console_put_char_ex( con, x, y, FLOOR_CONST, color_dark_ground, libtcod.dark_grey * libtcod.random_get_float(map_rng, 0.2, 0.5)) #draw all objects in the list for obj in objects: obj.draw() #blit the contents of "con" to the root console libtcod.console_blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0)
def addHill(hm,nbHill,baseRadius,radiusVar,height) : for i in range(nbHill) : hillMinRadius=baseRadius*(1.0-radiusVar) hillMaxRadius=baseRadius*(1.0+radiusVar) radius = libtcod.random_get_float(rnd,hillMinRadius, hillMaxRadius) theta = libtcod.random_get_float(rnd,0.0, 6.283185) # between 0 and 2Pi dist = libtcod.random_get_float(rnd,0.0, float(min(HM_WIDTH,HM_HEIGHT))/2 - radius) xh = int(HM_WIDTH/2 + math.cos(theta) * dist) yh = int(HM_HEIGHT/2 + math.sin(theta) * dist) libtcod.heightmap_add_hill(hm,float(xh),float(yh),radius,height)
def roll_room(self, x, y, xw, yh, min, max): #x=random.randrange(x,xw+1) #y=random.randrange(y,yh+1) x = int(libtcod.random_get_float(0, x, xw + 1)) y = int(libtcod.random_get_float(0, y, yh + 1)) print y w = int(libtcod.random_get_float(0, min, max + 1)) h = int(libtcod.random_get_float(0, min, max + 1)) # w=random.randrange(min,max+1) #h=random.randrange(min,max+1) return x, y, w, h
def attack(self, target): #random-rolled attack damage, with crits ran_hit = libtcod.random_get_float(0, 0, 1) ran_def = libtcod.random_get_float(0, 0, 1) if libtcod.random_get_float(0, 0, 100) > 90: ran_hit = 2 message(self.owner.name.capitalize() + ' PERFORMS A CRITICAL HIT!', 4294901887) damage = int(ran_hit * self.power - ran_def * target.fighter.defense) if damage > 0: #print self.owner.name.capitalize() + ' attacks ' + target.name + ' for ' + str(damage) + ' hit points.' message(self.owner.name.capitalize() + ' attacks ' + target.name + ' for ' + str(damage) + ' hit points.', 4286578559) target.fighter.take_damage(damage) else: #print self.owner.name.capitalize() + ' attacks ' + target.name + ' but has no effect.' message(self.owner.name.capitalize() + ' attacks ' + target.name + ' but has no effect.', 4282335231)
def create_dungeon(self): """ | Creates a random map | First, fills the map with walls. | Creates a BSP (Binary Space Partitioning) Tree and traverses it, creating a randomly-sized room for every node. | 50 % chance to spawn a random room feature, such as holes in the floor or columns. | Spawns the player on a random unblocked spot. | Then, calls *spawn_stuff()* to spawn mobs, items and the stairs """ from spawn import spawn_stuff from components import Object from roomfeatures import random_roomfeature #fill map with walls self.map = [[ Tile(char=chr(219), tile_type='wall', color=libtcod.grey * libtcod.random_get_float(0, 0.7, 1)) for y in range(gvar.MAP_HEIGHT) ] for x in range(gvar.MAP_WIDTH) ] #Create BSP Tree and Traverse it tree = libtcod.bsp_new_with_size(0, 0, gvar.MAP_WIDTH-2, gvar.MAP_HEIGHT-2) libtcod.bsp_split_recursive(tree, 0, 4, 8, 8, 1.3, 1.3) libtcod.bsp_traverse_post_order(tree, self.process_node, userData=0) #Random Roomfeature for room in self.rooms: if libtcod.random_get_int(0, 0, 2) == 0: random_roomfeature(self, room) spawn_stuff(self)
def cone_spray(num_particles, particle_array, ox, oy, dx, dy, random_decay=False, bounce=False): ay = oy - dy ax = ox - dx angle = math.atan2(float(-ay), float(-ax)) for i in range(num_particles): angle2 = angle + libtcod.random_get_float(0, -0.25, 0.25) velocity = 1.0 + libtcod.random_get_float(0, -0.05, 0.05) decay = 0.09 + libtcod.random_get_float(0, -0.05, 0.05) particle_array.append( Particle(ox, oy, decay, velocity, angle2, random_decay, bounce))
def test_random(): rand = libtcodpy.random_get_instance() rand = libtcodpy.random_new() libtcodpy.random_delete(rand) rand = libtcodpy.random_new_from_seed(42) libtcodpy.random_set_distribution(rand, libtcodpy.DISTRIBUTION_LINEAR) libtcodpy.random_get_int(rand, 0, 1) libtcodpy.random_get_int_mean(rand, 0, 1, 0) libtcodpy.random_get_float(rand, 0, 1) libtcodpy.random_get_double(rand, 0, 1) libtcodpy.random_get_float_mean(rand, 0, 1, 0) libtcodpy.random_get_double_mean(rand, 0, 1, 0) backup = libtcodpy.random_save(rand) libtcodpy.random_restore(rand, backup) libtcodpy.random_delete(rand) libtcodpy.random_delete(backup)
def randomize(self, type, min, max, times): result = 0 if type == 'float': for i in range(times): result += libtcod.random_get_float(self.rnd, min, max) if type == 'int': for i in range(times): result += libtcod.random_get_int(self.rnd, min, max) return result / times
def uniform_intensity_burst(color): factor = 3.0 clamp = 1.5 #generate a random number with a combined light intensity of 3.0 (brighter than any standard light) if not color: r = libtcod.random_get_float(0, 0.1, 1.5) g = libtcod.random_get_float(0, 0.1, 1.5) b = libtcod.random_get_float(0, 0.1, 1.5) else: r = color[0] / 255 g = color[1] / 255 b = color[2] / 255 #add them all together, then divide them by our target intensity s = r + g + b f = factor / s #then multiply the originally generated numbers by the factor to get target intensity r = min( clamp, r * f ) #but clamp to 1.5 intensity to prevent washout of a single color being too bright g = min(clamp, g * f) b = min(clamp, b * f) #get sum again (to maintain overall intensity, likely isnt completely accurate, #but it is close enough to the intention s = r + g + b f = factor / s if s < factor: if r == clamp: g = g * f b = b * f elif g == clamp: r = r * f b = b * f else: r = r * f g = g * f return (r, g, b)
def dig_ca_region(new_map, rect, gen1_count, gen2_count): # print('Dig cellular automata in rect ', rect) for x in range(rect.x1 + 1, rect.x2 - 1): for y in range(rect.y1 + 1, rect.y2 - 1): if libtcod.random_get_float(new_map.rng, 0., 1.) < 0.6: new_map.terrain[x][y] = map.TERRAIN_GROUND # Algorithm from http://www.roguebasin.com/index.php?title=Cellular_Automata_Method_for_Generating_Random_Cave-Like_Levels # Builds using map.TERRAIN_GROUND; we'll replace that with map.TERRAIN_FLOOR in a post-process for i in range(gen1_count): _generation(new_map, rect, 5, 2) for i in range(gen2_count): _generation(new_map, rect, 5, -1)
def place_objects(self, room): MAX_MONSTERS_IN_ROOM = 3 state = self.state num_monsters = libtcod.random_get_int(0, 0, MAX_MONSTERS_IN_ROOM) for i in range(num_monsters): x = libtcod.random_get_int(0, room.x1 + 1, room.x2 - 1) y = libtcod.random_get_int(0, room.y1 + 1, room.y2 - 1) die_throw = libtcod.random_get_float(0, 0, 1) if die_throw < 0.8: monster = Monster(state, (x, y), "orc", "o", libtcod.desaturated_green, hp=10, defense=0, power=3) else: monster = Monster(state, (x, y), "troll", "T", libtcod.darker_green, hp=13, defense=1, power=5) state.objects.add(monster)
def get_price(self, commodity, trade_house): believed = self.believed_prices[commodity][0] deviance = self.believed_prices[commodity][1] price = round(libtcod.random_get_float(0, believed - deviance, believed + deviance), 2) # modifier = trade_house.supply_demand[commodity][0] # if modifier != 0.0: # price = price if price < 0: print "uh-oh price of %s in %s is less than 0" % (commodity, trade_house.parent.name) price = believed # for now. #TODO: temporary until I can work out a better way to get a price. return price
def random(rng,pos,weight=1.0): if Monster.GENERATOR == []: Monster.__GEN_GENERATOR() max_weight = reduce( lambda a,b: a+b, [C.generator_weight for C in Monster.GENERATOR], 0.0 ) r = max_weight + 1.0 while r > max_weight: r = libtcod.random_get_float(rng,0.0,max_weight * weight) m_idx = 0 while r > Monster.GENERATOR[m_idx].generator_weight: r -= Monster.GENERATOR[m_idx].generator_weight m_idx += 1 return Monster.GENERATOR[m_idx](pos)
def get_all_tiles(rng, map_array, types=None): # for tile in tiles # tile.place_in(map_array) # for pattern in tile.patterns: # # list of pos where tile can be placed # ps = pattern.apply_to(map_array) # ps.sort(random_get_float) if types is None: types = [ FloorTeleport, FloorCharger, Crate, Window, Table, Locker, EvidencePanel, LightSwitch, ClankyFloor, TripWire, CameraConsole, TrapConsole ] ## naive way to do it (slow) #r = {} #for T in types: # r[T] = [] # for pattern in T.patterns: # r[T] += pattern.apply_to(map_array) # r[T].sort( key = lambda a: libtcod.random_get_float(rng,0.0,1.0) ) #return r # calculate which patterns are used by which objects, and apply each unique pattern once pattern_map = {} for T in types: for p in T.patterns: if not p in pattern_map.keys(): pattern_map[p] = [] pattern_map[p].append(T) r = {} for (p, T_list) in pattern_map.items(): p_list = p.apply_to(map_array) for T in T_list: if not T in r.keys(): r[T] = [] r[T] += p_list # randomize order of positions in list, so caller can just pop() them # NB. keys are sorted because this must be deterministic for map gen for T in sorted(r.keys(), key=lambda a: a.__name__): r[T].sort(key=lambda a: libtcod.random_get_float(rng, 0.0, 1.0)) return r
def mace_stun(attacker, target, damage): scaling_factor = 1 stun_duration = 1 if target.fighter is None: return if (attacker is player.instance): scaling_factor = attacker.player_stats.str / 10 if main.has_skill('ringing_blows'): scaling_factor *= 1.5 stun_duration = 2 if libtcod.random_get_float(0, 0.0, 1.0) * scaling_factor > 0.85: if attacker == player.instance: ui.message( "Your " + main.get_equipped_in_slot(player.instance.fighter.inventory, 'right hand').owner.name.title() + " rings out!", libtcod.blue) target.fighter.apply_status_effect(effects.stunned(stun_duration))
def talk(self, key=None): """Talk out loud, using a randomly chosen phrase based on key.""" if self.is_talking: self.stop_talk() if not key in self.__phrases.keys() or len(self.__phrases[key]['phrases']) == 0: return False if libtcod.random_get_float(None, 0.0, 1.0) < self.__phrases[key]['probability']: #assert key in self.__phrases.keys(), "Talker %s has no vocab for key %s"%(self,key) self.__chat.pos = self.pos - (0, 1) self.__chat.text = self.__phrases[key]['phrases'][ libtcod.random_get_int(None, 0, len(self.__phrases[key]['phrases']) - 1) ] self.is_talking = True self.__chat.is_visible = True self.currently_talking.add(self) if self.__phrases[key]['is_shouting']: self.shout() return True return False
def get_mat_from_rarity(self,type): ##============================================================================ r = libtcod.random_get_float(0,0.00000,1.00000) mat = None rarity = 1.0 if type == 'melee': for mats in self.weapon_mats: if mats.rarity >= r: if mats.rarity <= rarity: rarity = mats.rarity mat = mats return mat if type == 'armor': for mats in self.armor_mats: if mats.rarity >= r: if mats.rarity <= rarity: rarity = mats.rarity mat = mats return mat
def get_mat_from_rarity(self, type): ##============================================================================ r = libtcod.random_get_float(0, 0.00000, 1.00000) mat = None rarity = 1.0 if type == 'melee': for mats in self.weapon_mats: if mats.rarity >= r: if mats.rarity <= rarity: rarity = mats.rarity mat = mats return mat if type == 'armor': for mats in self.armor_mats: if mats.rarity >= r: if mats.rarity <= rarity: rarity = mats.rarity mat = mats return mat
def random(rng,pos,ranks=range(1,4),weight=1.0): """random item at pos using rng. fixing a rank will limit choice to that rank. raising weight increases probability of a good item""" # build cache of item ranks and weights if Item.AWESOME_MAP is None: Item.__GEN_AWESOME_MAP() if isinstance(ranks,int): ranks = [ranks] elif isinstance(ranks,list): ranks.sort() # calculate weighted range awesome_range = reduce( lambda a,b: a + b, [A[1][-1].awesome_acc_weight for A in Item.AWESOME_MAP.items() if A[0] in ranks], 0.0 ) # roll die and weight by parameter # NB. weighting can push t out of bounds! t = awesome_range + 1.0 while t >= awesome_range: t = libtcod.random_get_float(rng,0.0,awesome_range) * weight #print("Range = 0.0 - %f => %f" % (awesome_range,t)) # find rank that was rolled rank = ranks[0] while t > Item.AWESOME_MAP[rank][-1].awesome_acc_weight: t -= Item.AWESOME_MAP[rank][-1].awesome_acc_weight rank += 1 #print("Rank = %d => %s %s" %(rank,Item.AWESOME_MAP[rank],[C.awesome_acc_weight for C in Item.AWESOME_MAP[rank]])) # find item that was rolled item_idx = 0 while t > Item.AWESOME_MAP[rank][item_idx].awesome_acc_weight: item_idx += 1 # calculate item power (higher in range => more power) item_power = 2 * (Item.AWESOME_MAP[rank][item_idx].awesome_acc_weight-t) / Item.AWESOME_MAP[rank][item_idx].awesome_weight #print("Got %s (%d) at power %f" % (Item.AWESOME_MAP[rank][item_idx],item_idx,item_power)) return Item.AWESOME_MAP[rank][item_idx](pos,item_power)
def get_all_tiles(rng, map_array, types=None): # for tile in tiles # tile.place_in(map_array) # for pattern in tile.patterns: # # list of pos where tile can be placed # ps = pattern.apply_to(map_array) # ps.sort(random_get_float) if types is None: types = [FloorTeleport,FloorCharger,Crate,Window,Table,Locker,EvidencePanel,LightSwitch,ClankyFloor,TripWire,CameraConsole,TrapConsole] ## naive way to do it (slow) #r = {} #for T in types: # r[T] = [] # for pattern in T.patterns: # r[T] += pattern.apply_to(map_array) # r[T].sort( key = lambda a: libtcod.random_get_float(rng,0.0,1.0) ) #return r # calculate which patterns are used by which objects, and apply each unique pattern once pattern_map = {} for T in types: for p in T.patterns: if not p in pattern_map.keys(): pattern_map[p] = [] pattern_map[p].append(T) r = {} for (p,T_list) in pattern_map.items(): p_list = p.apply_to(map_array) for T in T_list: if not T in r.keys(): r[T] = [] r[T] += p_list # randomize order of positions in list, so caller can just pop() them # NB. keys are sorted because this must be deterministic for map gen for T in sorted(r.keys(), key=lambda a: a.__name__): r[T].sort( key = lambda a: libtcod.random_get_float(rng,0.0,1.0) ) return r
def talk(self, key=None): """Talk out loud, using a randomly chosen phrase based on key.""" if self.is_talking: self.stop_talk() if not key in self.__phrases.keys() or len( self.__phrases[key]['phrases']) == 0: return False if libtcod.random_get_float(None, 0.0, 1.0) < self.__phrases[key]['probability']: #assert key in self.__phrases.keys(), "Talker %s has no vocab for key %s"%(self,key) self.__chat.pos = self.pos - (0, 1) self.__chat.text = self.__phrases[key]['phrases'][ libtcod.random_get_int(None, 0, len(self.__phrases[key]['phrases']) - 1)] self.is_talking = True self.__chat.is_visible = True self.currently_talking.add(self) if self.__phrases[key]['is_shouting']: self.shout() return True return False
def cast_blizzard(): #find all monsters inside max range close_enemies = [] closest_dist = BLIZZARD_RANGE + 1 for object in objects: if object.fighter and not object == player and libtcod.map_is_in_fov(fov_map, object.x, object.y): #calculate distance between monster and player dist = player.distance_to(object) if dist < closest_dist: close_enemies.append(object) if len(close_enemies) == 0: message('No enemy is close enough to cast.', 4294901760) return 'cancelled' #kill them! for monster in close_enemies: damage = int(libtcod.random_get_float(0, 0, 1)*BLIZZARD_DAMAGE) if damage: message('The frosty beam zaps the ' + monster.name + ' for ' + str(damage) + ' hp!', 4282384191) else: message('The frosty beam misses the ' + monster.name + '!', 4294901760) monster.fighter.take_damage(damage)
def make_map(player, dungeon_level): """ """ old_map = player.current_map new_map = map.DungeonMap(MINE_SIZE, MINE_SIZE, dungeon_level) new_map.objects.append(player) player.current_map = new_map player.camera_position = algebra.Location(0, 0) new_map.random_seed = libtcod.random_save(0) new_map.rng = libtcod.random_new_from_seed(new_map.random_seed) old_quarry_stairs = old_map.quarry_stairs _link_up_stairs(new_map, old_map, old_quarry_stairs) _create_entries(new_map, old_quarry_stairs) _descend_stairs(new_map, player, old_quarry_stairs) _dig_some_caves(new_map, old_quarry_stairs) _dig_mine_tunnels(new_map) map_bounds = algebra.Rect(1, 1, new_map.width - 1, new_map.height - 1) for x in range(1, new_map.width - 1): for y in range(1, new_map.height - 1): if libtcod.random_get_float(new_map.rng, 0., 1.) < 0.2: new_map.terrain[x][y] = map.TERRAIN_GROUND ca_cartographer._generation(new_map, map_bounds, 7, 1) ca_cartographer._generation(new_map, map_bounds, 5, 1) # Redig the initial rooms because the CA can fill in the stairs for i in range(3): _create_room(new_map, new_map.rooms[i]) for i in range(3): stair_pos = old_quarry_stairs[i].dest_position ca_cartographer._floodfill(new_map, stair_pos.x, stair_pos.y, map.TERRAIN_GROUND, map.TERRAIN_FLOOR) for x in range(1, new_map.width - 1): for y in range(1, new_map.height - 1): if new_map.terrain[x][y] == map.TERRAIN_GROUND: new_map.terrain[x][y] = map.TERRAIN_WALL #for x in range(0, new_map.width): # new_map.terrain[x][0] = map.TERRAIN_WALL # new_map.terrain[x][new_map.height-1] = map.TERRAIN_WALL #for y in range(0, new_map.height): # new_map.terrain[0][y] = map.TERRAIN_WALL # new_map.terrain[new_map.width-1][y] = map.TERRAIN_WALL zone_divisor = MINE_SIZE / 3 slime_zone = new_map.rnd(0, 2) while True: undead_zone = new_map.rnd(0, 2) if undead_zone != slime_zone: break for r in range(3, len(new_map.rooms)): if new_map.rnd(1, 4) < 3: room = new_map.rooms[r] zone = room.center().x / zone_divisor if zone == slime_zone: if new_map.rnd(1, 2) == 1: bestiary.slime(new_map, _find_floor_near_room(new_map, room), player) bestiary.slime(new_map, _find_floor_near_room(new_map, room), player) else: bestiary.jelly(new_map, _find_floor_near_room(new_map, room), player) elif zone == undead_zone: bestiary.ghul(new_map, _find_floor_near_room(new_map, room), player) else: bestiary.worm(new_map, _find_floor_near_room(new_map, room), player) r = new_map.rnd(3, len(new_map.rooms) - 1) pos = new_map.rooms[r].center() while new_map.is_blocked_at(pos): pos += actions.random_direction() new_map.objects.insert(0, Object(pos, '%', "hero's corpse", libtcod.dark_red)) sword = miscellany.the_black_sword() sword.pos = pos new_map.objects.insert(0, sword) new_map.initialize_fov() new_map.xp_visit = _dungeon_exploration return False # Don't need to generate stairs in caller thanks to _link_up_stairs()
def spawn_mobs(self,game): ##Need to play around with values, mob spawning is too sparse or too great ##NEED MOAR MANA! if libtcod.map_is_in_fov(game.fov_map,self.x,self.y): ##if the node is in the view of the player, do nothing ##but schedule the next spawn turn self.ticker.schedule_turn(self.explored_speed,self.owner) else: ##Otherwise spawn mobs based on current threat level ##compared to maximum threat level ##unexplored tiles spawn mobs faster than explored ones #get the total threat from players equipped equipment threat=0.0 for item in game.player.fighter.equipment: if item: threat+=item.item.equipment.threat_level for item in game.player.fighter.accessories: if item: threat+=item.item.equipment.threat_level for item in game.player.fighter.wielded: if item: threat+=item.item.equipment.threat_level threat+=float(float(game.player.fighter.level)*2) #threat#*=2 #then get the current threat generated by current monsters current_threat = 0.0 for obj in game.objects: mob_threat = game.build_objects.get_threat_from_mob(obj.name) if mob_threat: current_threat+=mob_threat #to make sure unexplored areas are more dangerous #but dont spawn infinite mobs unexplored_threat = threat if current_threat < (threat*2.5): unexplored_threat=(threat*2.5) #left over threat that can be used for spawning threat-=current_threat unexplored_threat-=current_threat if self.tile.explored: self.ticker.schedule_turn(self.explored_speed,self.owner) if threat > 0.0: if threat > 4.0: max = 4.0 elif threat < 1.0: max = 1.0 else: max = threat r = libtcod.random_get_float(0,0.5,max) threat-=r #game.message.message("Monster Spawned") game.objects.append(game.build_objects.create_monster(game,self.x,self.y,threat_level=int(r))) else: #unexplored tiles respawn faster, and can spawn extra monsters self.ticker.schedule_turn(self.un_explored_speed,self.owner) if unexplored_threat > 0.0: if threat > 4.0: max = 4.0 elif unexplored_threat < 1.0: max = 1.0 else: max = unexplored_threat r = libtcod.random_get_float(0,0.5,max) unexplored_threat-=r #game.message.message("Monster Spawned") game.objects.append(game.build_objects.create_monster(game,self.x,self.y,threat_level=int(r))) for object in game.objects: object.message = game.message object.objects = game.objects
def rectify(val, max): if (val > max): val = max - (int)(tcod.random_get_float(0,0,1) * (max / 10)) elif (val < (max * -1)): val = (max * -1) + (int)(tcod.random_get_float(0,0,1) * (max / 10)) return val
def vary(number): return int(number + (number * libtcod.random_get_float(0, 0, const.VARIATION_PERCENT)) - (number * libtcod.random_get_float(0, 0, const.VARIATION_PERCENT)))
def vary(number): return int( number + (number * libtcod.random_get_float(0, 0, const.VARIATION_PERCENT)) - (number * libtcod.random_get_float(0, 0, const.VARIATION_PERCENT)))
def make_map(player, dungeon_level): """ """ old_map = player.current_map new_map = map.DungeonMap(MINE_SIZE, MINE_SIZE, dungeon_level) new_map.objects.append(player) player.current_map = new_map player.camera_position = algebra.Location(0, 0) new_map.random_seed = libtcod.random_save(0) new_map.rng = libtcod.random_new_from_seed(new_map.random_seed) old_quarry_stairs = old_map.quarry_stairs _link_up_stairs(new_map, old_map, old_quarry_stairs) _create_entries(new_map, old_quarry_stairs) _descend_stairs(new_map, player, old_quarry_stairs) _dig_some_caves(new_map, old_quarry_stairs) _dig_mine_tunnels(new_map) map_bounds = algebra.Rect(1, 1, new_map.width-1, new_map.height-1) for x in range(1, new_map.width-1): for y in range(1, new_map.height-1): if libtcod.random_get_float(new_map.rng, 0., 1.) < 0.2: new_map.terrain[x][y] = map.TERRAIN_GROUND ca_cartographer._generation(new_map, map_bounds, 7, 1) ca_cartographer._generation(new_map, map_bounds, 5, 1) # Redig the initial rooms because the CA can fill in the stairs for i in range(3): _create_room(new_map, new_map.rooms[i]) for i in range(3): stair_pos = old_quarry_stairs[i].dest_position ca_cartographer._floodfill(new_map, stair_pos.x, stair_pos.y, map.TERRAIN_GROUND, map.TERRAIN_FLOOR) for x in range(1, new_map.width-1): for y in range(1, new_map.height-1): if new_map.terrain[x][y] == map.TERRAIN_GROUND: new_map.terrain[x][y] = map.TERRAIN_WALL #for x in range(0, new_map.width): # new_map.terrain[x][0] = map.TERRAIN_WALL # new_map.terrain[x][new_map.height-1] = map.TERRAIN_WALL #for y in range(0, new_map.height): # new_map.terrain[0][y] = map.TERRAIN_WALL # new_map.terrain[new_map.width-1][y] = map.TERRAIN_WALL zone_divisor = MINE_SIZE / 3 slime_zone = new_map.rnd(0, 2) while True: undead_zone = new_map.rnd(0, 2) if undead_zone != slime_zone: break for r in range(3, len(new_map.rooms)): if new_map.rnd(1, 4) < 3: room = new_map.rooms[r] zone = room.center().x / zone_divisor if zone == slime_zone: if new_map.rnd(1, 2) == 1: bestiary.slime(new_map, _find_floor_near_room(new_map, room), player) bestiary.slime(new_map, _find_floor_near_room(new_map, room), player) else: bestiary.jelly(new_map, _find_floor_near_room(new_map, room), player) elif zone == undead_zone: bestiary.ghul(new_map, _find_floor_near_room(new_map, room), player) else: bestiary.worm(new_map, _find_floor_near_room(new_map, room), player) r = new_map.rnd(3, len(new_map.rooms) - 1) pos = new_map.rooms[r].center() while new_map.is_blocked_at(pos): pos += actions.random_direction() new_map.objects.insert(0, Object(pos, '%', "hero's corpse", libtcod.dark_red)) sword = miscellany.the_black_sword() sword.pos = pos new_map.objects.insert(0, sword) new_map.initialize_fov() new_map.xp_visit = _dungeon_exploration return False # Don't need to generate stairs in caller thanks to _link_up_stairs()
char='@', color=libtcod.white, mapref=the_map, torch_radius=10, ) cameras = [] for room in rooms[1:]: cameras.append(obj.Object( x=room.center()[0], y=room.center()[1], char='x', color=libtcod.red, mapref=the_map, torch_radius=8, fov_dir=libtcod.random_get_float(0, 0.0, 2.0 * math.pi) )) objects = [player] + cameras renderer = rendermeister.RenderMeister(drawlib=libtcod, fov_map=libtcod.map_new(the_map.width, the_map.height), mapref=the_map, objfocus=player, objrefs=objects) key_handler = keymeister.KeyMeister(keylib=libtcod) while not libtcod.console_is_window_closed(): renderer.render_all() libtcod.console_flush() renderer.clear_all() key_handler.handle_keys() if key_handler.fov_recompute:
def render_all(): global color_light_wall global color_light_ground map_rng = libtcod.random_new_from_seed(1, algo=libtcod.RNG_MT) #go through all tiles, and set their background color for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): wall = dungeon_map[x][y].block_sight if wall: libtcod.console_put_char_ex(con, x, y, WALL_CONST, color_dark_wall, libtcod.light_grey * libtcod.random_get_float(map_rng, 0.7, 0.8) ) else: libtcod.console_put_char_ex(con, x, y, FLOOR_CONST, color_dark_ground, libtcod.dark_grey * libtcod.random_get_float(map_rng, 0.2, 0.5) ) #draw all objects in the list for obj in objects: obj.draw() #blit the contents of "con" to the root console libtcod.console_blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0)
def mpd_getDisplacement(avg, _max): disp = int((avg + (2 * ((tcod.random_get_float(0,0,1)) - .5) * _max))); return disp;
def draw(self): if libtcod.random_get_float(None, 0.0, 1.0) < self.show_probability: self._show_wire() else: self._hide_wire() return Floor.draw(self)
def get_random_room(self): #a=random.randrange(0,len(self.roomlist)) a = int(libtcod.random_get_float(0, 0, len(self.roomlist))) return self.roomlist[a]
def get_random_tile(self, x=0, y=0, w=40, h=40): x = int(libtcod.random_get_float(0, x, x + w - 1)) y = int(libtcod.random_get_float(0, y, y + h - 1)) return x, y
def attack(self, target): #attack strength formula attack_strength = libtcod.random_get_float( 0, self.pow, self.pow * DAMAGE_STRENGTH_MULTIPLIER) attack_strength = int(round(attack_strength)) #damage formula damage = attack_strength - target.fighter.defense #placeholder var random_message = False attack_message = '' if ((damage) * CRIT_MULTIPLIER ) > 0: #checks if the critical attack would do any damage at all. if (libtcod.random_get_int(0, 0, 100) < CRIT_RATE): #critical damage - occurence rate defined by CRIT_RATE, and extra damage defined by CRIT_MULTIPLIER. #crit formula is - damage * crit_multi = damage - attack of 10 would do 22 on critical with 120% damage multiplier damage *= CRIT_MULTIPLIER # critical hit damage damage = int( round(damage) ) + target.fighter.defense # rounds up to nearest integer and bypasses enemy defense message(self.owner.name + ' lands a critical hit!', libtcod.light_red) #DAMAGE MESSAGES - each level of severity ( every 25% of max HP ) has increasingly brutal flavor text. #each level has 4-5 different sentences, chosen at random. if damage > 0: #make the target take damage, if it actually hurts. otherwise you'd end up healing the enemy! #choose a random attack onomatopoeia random_onoma = libtcod.random_get_int(0, 1, len(attack_onoma_msg) - 1) onoma = attack_onoma_msg[random_onoma] #sets attack color to white, just in case attack_color = libtcod.white # attack_0_10_msg - messages for damage of 0-24% of max HP if (damage < (0.1 * target.fighter.max_hp)): random_message = libtcod.random_get_int( 0, 0, len(attack_0_10_msg) - 1) attack_message = attack_0_10_msg[random_message] attack_color = libtcod.lightest_red # attack_10_35_msg - messages for damage of 25-49% of max HP elif (damage >= (0.1 * target.fighter.max_hp) and damage < (0.35 * target.fighter.max_hp)): random_message = libtcod.random_get_int( 0, 0, len(attack_10_35_msg) - 1) attack_message = attack_10_35_msg[random_message] attack_color = libtcod.lighter_red # attack_35_65_msg - messages for damage of 50-74% of max HP elif (damage >= (0.35 * target.fighter.max_hp) and damage < (0.65 * target.fighter.max_hp)): random_message = libtcod.random_get_int( 0, 0, len(attack_35_65_msg) - 1) attack_message = attack_35_65_msg[random_message] attack_color = libtcod.light_red # attack_65_85_msg - messages for damage of 75-85% of max HP elif (damage >= (0.65 * target.fighter.max_hp) and damage < (0.85 * target.fighter.max_hp)): random_message = libtcod.random_get_int( 0, 0, len(attack_65_85_msg) - 1) attack_message = attack_65_85_msg[random_message] attack_color = libtcod.red # attack_85_100_msg - messages for damage of 85%+ of max HP elif (damage >= (0.85 * target.fighter.max_hp)): random_message = libtcod.random_get_int( 0, 0, len(attack_85_100_msg) - 1) attack_message = attack_85_100_msg[random_message] attack_color = libtcod.dark_red message( onoma + '! ' + self.owner.name + ' ' + attack_message + ' ' + target.name + ' for ' + str(damage) + ' hitpoints.', attack_color) target.fighter.take_damage(damage) attack_onoma_msg.remove(onoma) attack_onoma_msg.insert(0, onoma) else: message(self.owner.name + ' feebly pokes ' + target.name + '.')
def sleeping_gas(x, y, radius, duration): path = util.set_full_explore_map(game.current_map) libtcod.dijkstra_compute(path, x, y) for i in range(-radius, radius + 1): for j in range(-radius, radius + 1): if libtcod.dijkstra_get_distance(path, x + i, y + j) <= radius and libtcod.dijkstra_get_distance(path, x + i, y + j) >= 0: game.current_map.tile[x + i][y + j].update({'icon': game.current_map.tile[x + i][y + j]['icon'], 'back_light_color': libtcod.Color(115, 220, 225), 'back_dark_color': libtcod.Color(0, 143, 189), 'lerp': round(libtcod.random_get_float(game.rnd, 0, 1), 1), 'duration': game.turns + duration, 'type': 'sleep_gas'}) for obj in game.current_map.objects: if obj.item is None: if obj.x == x + i and obj.y == y + j: if obj.name == 'player': game.message.new('You are caught in a sleeping cloud!', game.turns) if 'sleep' not in game.player.flags: dice = util.roll_dice(1, 50) if dice > game.player.wisdom + (game.player.karma / 2): game.message.new('You fall asleep!', game.turns, libtcod.Color(0, 143, 189)) game.player.flags.append('sleep') else: if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y): game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' is caught in a sleeping cloud!', game.turns) if 'sleep' not in obj.entity.flags: dice = util.roll_dice(1, 3) if dice == 3: if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y): game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' falls asleep!', game.turns) obj.entity.flags.append('sleep')
def draw(self): if libtcod.random_get_float(None,0.0,1.0) < self.show_probability: self._show_wire() else: self._hide_wire() return Floor.draw(self)
def __init__(self, mouth_col, mouth_row, heightmap, size, random): self.tiles = [] rainlevel = 90 # The level above which rivers have a drastically reduced chance to keep flowing. move = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0)] # Directions in order clockwise. flowing = True last_turns = 0 current_col = mouth_col current_row = mouth_row # Pick a starting direction: direct = lt.random_get_int(random, 0, 7) # The first direction we'll go. while flowing: if 0 <= current_col < size and 0 <= current_row < size: self.tiles.append((current_col, current_row)) found = tuple() # Build a new list including the two options around the starting directions. new_move = [move[direct - 1], move[direct], move[direct + 1 if direct < 7 else 0]] for direction in new_move: dx, dy = direction value = lt.heightmap_get_value(heightmap, current_row + dx, current_col + dy) here = lt.heightmap_get_value(heightmap, current_row, current_col) if value > here: if found: if found[1] > value: found = (direction, value) else: found = (direction, value) break if found: if found[0] == new_move[0]: if last_turns < -2: found = (new_move[1], 0) else: last_turns -= 2 if found[0] == new_move[2]: if last_turns > 3: found = (new_move[1], 0) else: last_turns += 3 dx, dy = found[0] last_turns += 1 if last_turns < 0 else -1 elif len(found) == 0: dx, dy = new_move[1] if here < -19: flowing = False direct = move.index((dx, dy)) current_col += dy current_row += dx if current_col == size or current_row == size or current_col < 0 or current_col < 0: flowing = False if (current_col, current_row) in self.tiles: flowing = False # Check if we should still be flowing. chance = lt.random_get_float(random, 0, 1) if here > rainlevel and chance < 0.4: flowing = False elif chance < (len(self.tiles) * 0.0005) * (here * 0.00005): flowing = False self.head_col = current_col self.head_row = current_row
def fireball(x, y, radius): path = util.set_full_explore_map(game.current_map) libtcod.dijkstra_compute(path, x, y) for step in range(0, radius + 1): player_fov = False for i in range(-radius, radius + 1): for j in range(-radius, radius + 1): if libtcod.map_is_in_fov(game.fov_map, x + i, y + j) and libtcod.dijkstra_get_distance(path, x + i, y + j) <= step and libtcod.dijkstra_get_distance(path, x + i, y + j) >= 0: (front, back, lerp) = util.render_tiles_animations(x + i, y + j, libtcod.Color(160, 0, 0), libtcod.Color(64, 0, 0), libtcod.Color(0, 0, 0), round(libtcod.random_get_float(game.rnd, 0, 1), 1)) libtcod.console_put_char_ex(0, game.MAP_X + x - game.curx + i, game.MAP_Y + y - game.cury + j, '*', front, back) player_fov = True if player_fov: libtcod.console_flush() time.sleep(0.05) player_fov = False for obj in game.current_map.objects: damage = util.roll_dice(1, 10) if obj.name == 'player': if libtcod.dijkstra_get_distance(path, game.char.x, game.char.y) <= radius: game.message.new('You are hit by a fireball for ' + str(damage) + ' pts of damage!', game.turns, libtcod.Color(160, 0, 0)) game.player.take_damage(damage, 'a fireball') elif obj.entity: if libtcod.dijkstra_get_distance(path, obj.x, obj.y) <= radius: obj.entity.take_damage(obj.x, obj.y, damage, 'a fireball', True)