def addsgskill(self, skillname: str, skillvalue: int, card1: GameCard, update: Update) -> bool: """添加一个建议的技能。直接调用`addmainskill`完成。""" if not self.addmainskill(skillname, skillvalue, card1, update): return False card1.suggestskill.pop(skillname) card1.write() return True
def addmainskill(self, skillname: str, skillvalue: int, card1: GameCard, update: Update) -> bool: """该函数对没有`skillname`这项技能的卡使用。将主要技能值设置为`skillvalue`。""" if card1.skill.points == 0: return self.errorInfo("你已经没有剩余点数了") if skillvalue < self.getskilllevelfromdict( card1, skillname) or skillvalue > self.skillmaxval( skillname, card1, True): return self.errorInfo("目标技能点太高或太低") # 计算点数消耗 costval = self.evalskillcost(skillname, skillvalue, card1, True) self.reply("技能设置成功:" + skillname + " " + str(skillvalue) + ",消耗点数:" + str(costval)) card1.skill.set(skillname, skillvalue, costval) card1.write() return True
def groupcopy(self, oldgpid: int, newgpid: int, copyall: bool) -> bool: """copyall为False则只复制NPC卡片""" if self.findexistgame(oldgpid) is not None or self.findexistgame(newgpid) is not None: return False oldgp = self.forcegetgroup(oldgpid) srclist: List[GameCard] = [] for card in oldgp.cards.values(): if not copyall and card.type == "PL": continue srclist.append(card) if len(srclist) == 0: return False newids = self.getnewids(len(srclist)) dstlist = [GameCard(card.to_json()) for card in srclist] for i in range(len(dstlist)): dstlist[i].id = newids[i] for card in dstlist: self.addcardoverride(card, newgpid) self.getgp(newgpid).write() oldgp.write() return True
def cgmainskill(self, skillname: str, skillvalue: int, card1: GameCard, update: Update) -> bool: """修改主要技能的值。如果将技能点调低,返还技能点数。""" if skillvalue < self.getskilllevelfromdict( card1, skillname) or skillvalue > self.skillmaxval( skillname, card1, True): return self.errorInfo("目标技能点太高或太低") costval = self.evalskillcost(skillname, skillvalue, card1, True) if costval >= 0: self.reply("技能设置成功:" + skillname + " " + str(skillvalue) + ",消耗点数:" + str(costval)) else: self.reply("技能设置成功:" + skillname + " " + str(skillvalue) + ",返还点数:" + str(-costval)) card1.skill.set(skillname, skillvalue, costval) card1.write() return True
def continuegame(self, update: Update, context: CallbackContext) -> bool: """继续游戏。必须在`/pausegame`之后使用。 游戏被暂停时,可以视为游戏不存在,游戏中卡片被暂时保护起来。 当有中途加入的玩家时,使用该指令先暂停游戏,再继续游戏即可将新的角色卡加入进来。 可以在暂停时(或暂停前)修改:姓名、性别、随身物品、财产、背景故事, 继续游戏后会覆盖游戏中的这些属性。""" if not isgroup(update): return self.errorInfo("发送群消息暂停游戏") gp = self.forcegetgroup(update) kp = self.forcegetplayer(update) if gp.kp != kp: return self.errorInfo("只有KP可以暂停游戏", True) if gp.pausedgame is None: return self.errorInfo("没有进行中的游戏", True) for card in gp.pausedgame.cards.values(): outcard = gp.getcard(card.id) assert(outcard is not None) card.info.name = outcard.info.name card.info.sex = outcard.info.sex card.item = outcard.item.copy() card.assets = outcard.assets card.background = CardBackground(d=outcard.background.to_json()) for card in gp.cards.values(): if card.id not in gp.pausedgame.cards: ngcard = GameCard(card.to_json()) ngcard.isgamecard = True self.addgamecard(ngcard) gp.game = gp.pausedgame gp.pausedgame = None gp.write() self.reply("游戏继续!") return True
def addcard(self, update: Update, context: CallbackContext) -> bool: """使用已有信息添加一张卡片,模板使用的是NPC/怪物模板。指令格式如下: `/addcard --attr_1 --val_1 --attr_2 --val_2 …… --attr_n -- val_n`, 其中`attr`是卡的直接属性或子属性。 卡的属性只有三种类型的值:`int`, `str`, `bool`,其他类型暂不支持用本指令。 函数会自动判断对应的属性是什么类型,其中`bool`类型`attr`对应的`val`只能是`true`, `True`, `false`, `False`之一。 不可以直接添加tempstatus这个属性。 如果需要添加主要技能点数,用mainpoints作为`attr`,兴趣技能点则用intpoints,清不要使用points。 如果要添加特殊技能,比如怪物的技能,请令`attr`为`specialskill`,`val`为`特殊技能名:技能值`。 技能值是正整数,技能名和技能值用英文冒号分开。 `name`和背景信息不支持空格,如果要设置这一项信息,需要之后用`/setbkg`来修改,所以尽量不要用该指令设置背景信息。 如果遇到无法识别的属性,将无法创建卡片。 参数中,必须的`attr`之一为`groupid`,如果找不到`groupid`将无法添加卡片。 `playerid`会自动识别为发送者,无需填写`playerid`。 指令使用者是KP的情况下,才可以指定`playerid`这个属性,否则卡片无效。 给定`id`属性的话,在指定的卡id已经被占用的时候,会重新自动选取。""" if isgroup(update): return self.errorInfo("向我发送私聊消息来添加卡", True) if len(context.args) == 0: return self.errorInfo("需要参数") if (len(context.args)//2)*2 != len(context.args): self.reply("参数长度应该是偶数") t = templateNewCard() # 遍历args获取attr和val mem: List[str] = [] for i in range(0, len(context.args), 2): argname: str = context.args[i] if argname in mem: return self.errorInfo(argname+"属性重复赋值") mem.append(argname) argval = context.args[i+1] if argname == "specialskill": skillname, skillval = argval.split(":") if not isint(skillval) or int(skillval) <= 0: return self.errorInfo("技能值应该是正整数") t["skill"]["skills"][skillname] = int(skillval) continue if argname == "points": return self.errorInfo("points应指明是mainpoints还是intpoints") if argname == "mainpoints": argname = "points" dt = t["skill"] elif argname == "intpoints": argname = "points" dt = t["interest"] dt = findattrindict(t, argname) if not dt: # 可能是技能,否则返回 if argname in self.skilllist or argname == "母语" or argname == "闪避": if not isint(argval) or int(argval) <= 0: return self.errorInfo("技能值应该是正整数") dt: dict = t["skill"]["skills"] dt[argname] = 0 # 这一行是为了防止之后判断类型报错 else: return self.errorInfo("属性 "+argname+" 在角色卡模板中没有找到") if isinstance(dt[argname], dict): return self.errorInfo(argname+"是dict类型,不可直接赋值") if type(dt[argname]) is bool: if argval == "false" or argval == "False": argval = False elif argval == "true" or argval == "True": argval = True if not type(argval) is bool: return self.errorInfo(argname+"应该为bool类型") dt[argname] = argval elif type(dt[argname]) is int: if not isint(argval): return self.errorInfo(argname+"应该为int类型") dt[argname] = int(argval) else: dt[argname] = argval # 参数写入完成 # 检查groupid是否输入了 if t["groupid"] == 0: return self.errorInfo("需要groupid!") # 检查是否输入了以及是否有权限输入playerid pl = self.forcegetplayer(update) if not self.searchifkp(pl): if t["playerid"] != 0 and t["playerid"] != pl.id: return self.errorInfo("没有权限设置非自己的playerid") t["playerid"] = getchatid(update) else: if t["groupid"] not in pl.kpgroups and t["playerid"] != 0 and t["playerid"] != pl.id: return self.errorInfo("没有权限设置非自己的playerid") if t["playerid"] == 0: t["playerid"] = pl.id # 生成成功 card1 = GameCard(t) # 添加id if "id" not in context.args or card1.id < 0 or card1.id in self.allids: self.reply("输入了已被占用的id,或id未设置,或id无效。自动获取id") card1.id = self.getoneid() # 生成衍生数值 card1.generateOtherAttributes() # 卡检查 rttext = card1.check() if rttext != "": self.reply( "卡片添加成功,但没有通过开始游戏的检查。") self.reply(rttext) else: self.reply("卡片添加成功") return True if self.addonecard(card1) else self.errorInfo("卡id重复")